Kotlin简单封装OkHttp与Gson

作者: 沐小晨曦 | 来源:发表于2018-08-06 20:38 被阅读14次

    前言

    看了公司封装的网络请求,就是对OkHttp和Gson的封装。看了一下代码,里面好多都是鸿洋大佬写的 okhttp-utils 。当然,光看不写还是很难领悟,于是想用Kotlin来试着写写看。

    在这之前,先看我之前封装的简单的写法(只贴出异步Get请求):

    public class OkHttpUtil {
        private static OkHttpUtil sOkHttpUtil = null;
        private OkHttpClient mHttpClient;
        private Request mRequest;
    
        private OkHttpUtil(){
    
        }
    
        public static OkHttpUtil getInstance() {
            if (sOkHttpUtil == null) {
                synchronized (OkHttpUtil.class) {
                    if (sOkHttpUtil == null) {
                        sOkHttpUtil = new OkHttpUtil();
                    }
                }
            }
            return sOkHttpUtil;
        }
    
        public void startGet(String url, final OnNetResultListener listener) {
            mHttpClient = new OkHttpClient();
            mRequest = new Request.Builder().url(url).build();
            mHttpClient.newCall(mRequest).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    listener.onFailureListener(e.getMessage());
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    listener.onSuccessListener(response.body().string());
                }
            });
        }
    }
    

    其实就是用接口回调结果,但这样有两个问题:

    • 每次都要拿到回调结果后手动反序列化
    • 回调在非UI线程,也就是还的写Handle处理

    那能不能一步到位呢?当然可以,最终写法如下:

            OkHttpClientManager.getAsync(url,object :ResultCallback<ResultBean>(){
                override fun onError(request: Request, exception: Exception) {
    
                }
    
                override fun onResponse(response: ResultBean) {
                    mTextView.text = response.name
                }
            })
    

    其实实现也很简单,关键是怎么把泛型参数转化为具体的JavaBean实例,完整源码如下,只贴出了GET请求:

    package top.omooo.mylibrary.network
    
    import android.os.Handler
    import android.os.Looper
    import com.google.gson.Gson
    import com.google.gson.internal.`$Gson$Types`
    import okhttp3.*
    import java.io.IOException
    import java.lang.reflect.ParameterizedType
    import java.lang.reflect.Type
    
    /**
     *  Created by ssc on 2018/8/6.
     */
    object OkHttpClientManager {
        private val mOkHttpClient by lazy {
            OkHttpClient()
        }
        private val mHandler by lazy {
            Handler(Looper.getMainLooper())
        }
        private val mGson by lazy {
            Gson()
        }
    
        //同步Get请求
        private fun getSync(url: String): Response {
            val request = Request.Builder()
                    .url(url)
                    .build()
            val call = mOkHttpClient.newCall(request)
            return call.execute()
        }
    
        fun getSyncString(url: String): String {
            return getSync(url).body()!!.string()
        }
    
        //异步Get请求
        fun getAsync(url: String, callback: ResultCallback<*>) {
            val request = Request.Builder()
                    .url(url)
                    .build()
            deliverResult(callback, request)
        }
    
        private fun deliverResult(callback: ResultCallback<*>, request: Request) {
            mOkHttpClient.newCall(request).enqueue(object : Callback {
                override fun onFailure(call: Call?, e: IOException) {
                    sendFailedStringCallback(request, e, callback)
                }
    
                override fun onResponse(call: Call?, response: Response?) {
                    val string = response?.body()!!.string()
                    val mObject = mGson.fromJson<Any>(string, callback.mType)
                    sendSuccessResultCallback(mObject, callback as ResultCallback<Any>)
                }
            })
        }
    
        fun sendFailedStringCallback(request: Request, exception: Exception, callback: ResultCallback<*>) {
            mHandler.post {
                callback.onError(request, exception)
            }
        }
    
        fun sendSuccessResultCallback(mObject: Any, callback: ResultCallback<Any>) {
            mHandler.post {
                callback.onResponse(mObject)
            }
        }
    }
    
    abstract class ResultCallback<T> {
        val mType: Type  by lazy {
            getSuperclassTypeParameter(javaClass)
        }
    
        companion object {
            fun getSuperclassTypeParameter(subclass: Class<*>): Type {
                val superclass = subclass.genericSuperclass
                if (superclass is Class<*>) {
                    throw RuntimeException("Miss type parameter.")
                }
                val parameterizedType = superclass as ParameterizedType
                return `$Gson$Types`.canonicalize(parameterizedType.actualTypeArguments[0])
            }
        }
    
        abstract fun onError(request: Request, exception: Exception)
        abstract fun onResponse(response: T)
    }
    

    最后

    可以参考鸿洋大佬的 Android OkHttp完全解析 是时候来了解OkHttp了

    事实上,博客中的代码相对okhttp-utils 还是很简单的。

    相关文章

      网友评论

        本文标题:Kotlin简单封装OkHttp与Gson

        本文链接:https://www.haomeiwen.com/subject/rwxnvftx.html