前言
看了公司封装的网络请求,就是对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.networkimport android.os.Handlerimport android.os.Looperimport com.google.gson.Gsonimport com.google.gson.internal.`$Gson$Types`import okhttp3.*import java.io.IOExceptionimport java.lang.reflect.ParameterizedTypeimport 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)}
作者:沐小晨曦
链接:https://www.jianshu.com/p/fb56bb9d2c7d