• AndroidSDK开发6我用kotlin写了一个简单sdk


    目录

    AndroidSDK开发6我用kotlin写了一个简单sdk

    1.kotlin的依赖和导包如下:

    (如果不使用协程可以去掉协程的导包减少sdk包大小)

    2.Application代码如下:

    3.常量工具类(Constants):

    4.日志工具类(LogUtils):

    5.网络状态工具类(NetWorkUtils):

    6.初始化及管理工具类(WanAndroidManager):

    7.网络请求工具类:

    8.网络请求接口监听:

    9.网络请求结果解析工具类:

    10.网络请求接口回调方法:

    11.网络请求线程工具类:

    12.网络请求回调:

    13.网络请求封装的具体方法:

    14.具体测试代码如下:

    15.运行效果截图和日志:

    15.1 具体实现效果截图如下:

    15.2 运行日志如下:

    16.项目源码地址如下(分支选择dev_kotlin):


    AndroidSDK开发6我用kotlin写了一个简单sdk

    由于前面几篇文章讲解了sdk初始化、sdk设计原则、将moule或者项目打成aar、不用第三方库开发一个sdk等,目前市面上很少有使用sdk开发采用kotlin语言,本文讲解使用如何使用kolin开发一个简单sdk,当然这里有2个版本,由于最开始没有使用协程导致使用和代码还是很多,经过之前的经验和sdk使用原则以及对新语言的使用情况,于是产生了使用加入协程的概念,具体使用如下:

    1.kotlin的依赖和导包如下:

    (如果不使用协程可以去掉协程的导包减少sdk包大小)

    //apply plugin: 'com.android.application'
    apply plugin: 'com.android.library'
    apply plugin: 'kotlin-android'
    apply plugin: 'kotlin-android-extensions'
    apply plugin: 'kotlin-kapt'

      dependencies {   implementation fileTree(dir: "libs", include: ["*.jar"])   implementation 'androidx.appcompat:appcompat:1.1.0'   implementation 'androidx.constraintlayout:constraintlayout:1.1.3'   implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"   implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"   implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinx_coroutines_version}" }

    2.Application代码如下:

    /**
     * @auth: njb
     * @date: 2022/4/27 15:56
     * @desc: 描述
     */
    class App : Application() {
    ​
        override fun onCreate() {
            super.onCreate()
            context = applicationContext
        }
    ​
        companion object{
            var context: Context by Delegates.notNull()
                private set
        }
    }
    

    3.常量工具类(Constants):

    /**
     * @auth: njb
     * @date: 2022/4/25 11:43
     * @desc: 常量工具类
     */
    object Constants {
        const val BASE_URL = "https://www.wanandroid.com"
        const val DEFAULT_TIMEOUT = 20000 //10秒
        const val TAG = "WanHttp"
        //搜索
        const val QUERY_ARTICLE = "/article/query/0/json"
        //获取首页banner列表
        const val BANNER_LIST = "/banner/json"
        //搜索热词
        const val HOT_KEY = "/hotkey/json"
    }

    4.日志工具类(LogUtils):

    /**
     * @auth: njb
     * @date: 2022/4/26 14:26
     * @desc: 日志工具类
     */
    object LogUtils {
        const val showLog:Boolean = true
    ​
        fun i(tag: String, msg: String) {
            if (showLog) Log.i(tag, msg)
        }
    ​
        fun d(tag: String, msg: String) {
            if (showLog) Log.d(tag, msg)
        }
    ​
        fun w(tag: String, msg: String) {
            if (showLog) Log.w(tag, msg)
        }
    ​
        fun e(tag: String, msg: String) {
            if (showLog) Log.e(tag, msg)
        }
    }

    5.网络状态工具类(NetWorkUtils):

    /**
     * @auth: njb
     * @date: 2022/4/27 11:45
     * @desc: 网络状态工具类
     */
    class NetWorkUtils {
        companion object{
            @get:RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
            val isConnected: Boolean
                get() {
                    val info = activeNetworkInfo
                    return info.isConnected
                }
    ​
            @get:RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
            private val activeNetworkInfo: NetworkInfo
                get() {
                    val cm = App.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                    return cm.activeNetworkInfo!!
                }
        }
    }

    6.初始化及管理工具类(WanAndroidManager):

    /**
     * @auth: njb
     * @date: 2022/4/23 22:39
     * @desc: 描述
     */
    class WanAndroidManager() {
        var mContext:Context by Delegates.notNull()
    ​
        fun init(app: Application){
            mContext = app.applicationContext
        }
    }

    7.网络请求工具类:

    class WanHttpUtils {
        companion object {
            lateinit var connection: HttpURLConnection
            fun doRequestPost(params: Map): WanAndroidHttpResult {
                val result by lazy { WanAndroidHttpResult() }
                try {
                    runBlocking {
                        withContext(Dispatchers.Default) {
                            val url by lazy { URL(params["url"]) }
                            LogUtils.d(Constants.TAG, "$url --url--")
                            setConnection(url, params)
                            LogUtils.d(Constants.TAG, "$params --params--")
                            val requestParamJsonObject by lazy { params["body"] }
                            if (requestParamJsonObject != null && "" != requestParamJsonObject?.trim { it <= ' ' }) {
                                val bytes by lazy { requestParamJsonObject?.toByteArray() }
                                connection.setRequestProperty("Content-Length", bytes?.size.toString())
                                val outputStream by lazy { connection.outputStream }
                                outputStream.run {
                                    write(bytes)
                                    flush()
                                    close()
                                }
                            }
                            setResult(responseCode = connection.responseCode, result)
                        }
                    }
                } catch (e: Exception) {
                    showErrorMsg(result, e)
                } finally {
                    connection.disconnect()
                }
                return result
            }
    ​
            fun doRequestGet(params: Map): WanAndroidHttpResult? {
                val result by lazy { WanAndroidHttpResult() }
                runBlocking {
                    withContext(Dispatchers.Default) {
                        try {
                            val url by lazy { URL(params["url"]) }
                            setConnection(url, params)
                            setResult(responseCode = connection.responseCode, result)
                        } catch (e: Exception) {
                            showErrorMsg(result, e)
                        }
                    }
                }
                return result
            }
    ​
            private fun setResult(responseCode: Int, result: WanAndroidHttpResult) {
                result.run {
                    responseCode.run {
                        if (this == 200) {
                            isBizSucceed(true)
                            setData(getResponseDataString(connection.inputStream))
                        } else {
                            isBizSucceed(false)
                            setData("")
                            result.errorMsg =
                                "errorCode:" + responseCode + connection.responseMessage
                        }
                    }
                }
            }
    ​
            private fun setConnection(
                url: URL,
                params: Map,
            ) {
                connection = (url.openConnection() as HttpURLConnection).apply {
                    readTimeout = DEFAULT_TIMEOUT
                    connectTimeout = DEFAULT_TIMEOUT
                    doOutput = true
                    doInput = true
                    requestMethod = params["Method"]
                    setRequestProperty("Connection", "Keep-Alive")
                    setRequestProperty("Charset", "UTF-8")
                    setRequestProperty("Content-Type", "application/json; charset=UTF-8")
                    setRequestProperty("accept", "application/json")
                }
            }
    ​
            private fun showErrorMsg(result: WanAndroidHttpResult, e: Exception) {
                val msg: Any
                msg = when {
                    !isConnected -> {
                        "网络连接失败,请检查网络"
                    }
                    e is SocketTimeoutException -> {
                        "网络请求超时,请稍后重试"
                    }
                    e is MalformedJsonException -> {
                        "数据解析失败"
                    }
                    else -> {
                        "请求失败,请稍后重试:" + e.message
                    }
                }
                result.errorMsg = msg
            }
    ​
            private fun getResponseDataString(inputStream: InputStream): String {
                val inputStreamReader by lazy { InputStreamReader(inputStream) }
                val bufferedReader by lazy { BufferedReader(inputStreamReader) }
                val stringBuilder by lazy { StringBuilder() }
                var temp: String?
                try {
                    while (bufferedReader.readLine().also { temp = it } != null) {
                        stringBuilder.append(temp)
                    }
                } catch (e: IOException) {
                    e.printStackTrace()
                } finally {
                    try {
                        bufferedReader.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                    try {
                        inputStreamReader.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                    try {
                        inputStream.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
                return stringBuilder.toString()
            }
        }
    }

    8.网络请求接口监听:

    /**
     * @auth: njb
     * @date: 2022/6/10 15:59
     * @desc: 描述
     */
    interface OnResponseListener {
       suspend fun onResponse(wanAndroidHttpResult: WanAndroidHttpResult<*>?)
    }

    9.网络请求结果解析工具类:

    /**
     * @auth: njb
     * @date: 2022/4/22 15:53
     * @desc: 描述
     */
    class WanAndroidHttpResult {
        /**
         * 记录请求回来的错误状态描述
         */
        private var errorCode:Int ?=0
    ​
        /**
         * 记录请求回来的错误状态描述
         */
        var errorMsg = ""
    ​
        /**
         * 记录返回的数据
         */
        var data: T? = null
            private set
    ​
        /**
         * 业务请求是否成功
         */
        fun isBizSucceed(defaultValue: Boolean): Boolean {
            return if (null == errorCode) defaultValue else errorCode == 0
        }
    ​
        fun setData(data: T) {
            this.data = data
        }
    }

    10.网络请求接口回调方法:

    /**
     * @auth: njb
     * @date: 2022/4/22 15:33
     * @desc: 描述
     */
    interface WanHttpRequestCallBack {
        fun onResponse(response: String?): Boolean?
    ​
        fun onFailed(message: String?): Boolean?
    }

    11.网络请求线程工具类:

    /**
     * @auth: njb
     * @date: 2022/6/6 10:06
     * @desc: 描述
     */
    open class WanRequestThread(
        private val params: Map,
        private val listener: OnResponseListener
    ) {
        private val lock by lazy { ByteArray(0) }
        private var isCancel = false
    ​
        suspend fun run() {
            val result: WanAndroidHttpResult? =
                if (params["Method"] == "POST") WanHttpUtils.doRequestPost(params) else WanHttpUtils.doRequestGet(params)
                if (!isCancel) {
                    listener.onResponse(result)
                }
        }
    ​
        suspend fun cancel() {
            synchronized(lock) { isCancel = true }
        }
    }

    12.网络请求回调:

    /**
     * @auth: njb
     * @date: 2022/6/6 10:27
     * @desc: 描述
     */
    class WanRequestListener {
        companion object{
            suspend fun getQueryArticle(responseListener: OnResponseListener, keyWord:String): WanRequestThread {
                val params by lazy { HashMap() }
                val url by lazy { Constants.BASE_URL + Constants.QUERY_ARTICLE + "?k="+keyWord }
                params["url"] = url
                params["Method"] = "POST"
                val requestThread by lazy { WanRequestThread(params, responseListener) }
                requestThread.run()
                return requestThread
            }
        }
    ​
        suspend fun getHomeBanner(responseListener: OnResponseListener):WanRequestThread{
            val params by lazy { HashMap() }
            val url by lazy { Constants.BASE_URL + Constants.BANNER_LIST }
            params["url"] = url
            params["Method"] = "GET"
            val requestThread by lazy { WanRequestThread(params, responseListener) }
            requestThread.run()
            return requestThread
        }
    }

    13.网络请求封装的具体方法:

    /**
     * @auth: njb
     * @date: 2022/5/2 22:37
     * @desc: 描述
     */
    object WanHttpRequest {
        suspend fun queryArticle(callBack: WanHttpRequestCallBack,keyWord:String){
            WanRequestListener.getQueryArticle(object : OnResponseListener {
                override suspend fun onResponse(wanAndroidHttpResult: WanAndroidHttpResult<*>?) {
                    if (wanAndroidHttpResult == null && wanAndroidHttpResult?.data == null) {
                        return
                    }
                    try {
                        val content by lazy { wanAndroidHttpResult.data.toString() }
                        wanAndroidHttpResult.run {
                            callBack.run {
                                if (isBizSucceed(true)) {
                                    onResponse(content)
                                } else {
                                    val message by lazy { wanAndroidHttpResult.errorMsg }
                                    onFailed(message)
                                }
                            }
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            },keyWord)
        }
    }

    14.具体测试代码如下:

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            initView()
        }
    ​
        private fun initView() {
            getQueryData()
        }
    ​
        private fun getQueryData() {
            GlobalScope.launch(Dispatchers.Main) {
                WanHttpRequest.queryArticle(object : WanHttpRequestCallBack {
                    override fun onResponse(response: String?): Boolean? {
                        try {
                            val jsonObject by lazy { JSONObject(response) }
                            val jsonObject2 = jsonObject.getJSONObject("data")
                            val jsonArray by lazy { jsonObject2.getJSONArray("datas") }
                            val list: MutableList = ArrayList()
                            if (jsonArray.length() > 0) {
                                for (i in 0 until jsonArray.length()) {
                                    val datasBean = ArticleListDataBean()
                                    val bannerObject: JSONObject = jsonArray.getJSONObject(i)
                                    datasBean.run {
                                        bannerObject.run {
                                            id = bannerObject.getInt("id")
                                            link = bannerObject.getString("link")
                                            desc = bannerObject.getString("desc")
                                            apkLink = bannerObject.getString("apkLink")
                                            title = bannerObject.getString("title")
                                            chapterName = bannerObject.getString("chapterName")
                                        }
                                        list.add(this)
                                    }
                                }
                                CoroutineScope(Dispatchers.IO).launch {
                                    list.forEach { it ->
                                        Log.d("---MainActivity---", it.chapterName + " 数据获取成功 ")
                                        tvTest.text = it.chapterName
                                    }
                                }
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                        return null
                    }
                    override fun onFailed(message: String?): Boolean? {
                        return null
                    }
                }, "Android")
            }
        }
    }

    15.运行效果截图和日志:

    15.1 具体实现效果截图如下:

    /**这里使用的是鸿洋的WanAndroidApi,只是写了一个简单的接口测试,没有写具体的逻辑 **/

    15.2 运行日志如下:

    16.项目源码地址如下(分支选择dev_kotlin):

    wanandroidsdkHttp: 利用鸿神wanandroidapi封装的简单sdk,没有使用任何第三方

  • 相关阅读:
    C语言实现栈的基本操作
    城市内涝监测预警系统:有效降低内涝风险,保障城市安全
    欧科云链研究院:锚定金融市场,香港从STO再出发
    C语言学习笔记(三)
    基于JAVA助农脱贫系统计算机毕业设计源码+系统+数据库+lw文档+部署
    【深度学习】优化算法浅记
    不平衡数据处理--学习笔记
    技巧与思想——位运算
    编译openMVG出现的错误的解决
    JDBC-day06(数据库连接池)
  • 原文地址:https://blog.csdn.net/u012556114/article/details/126684618