Kotlin簡單封裝OkHttp與Gson

前言

看了公司封裝的網(wǎng)絡請求,就是對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
            }
        })

其實實現(xiàn)也很簡單,關鍵是怎么把泛型參數(shù)轉化為具體的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 還是很簡單的。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,741評論 25 709
  • http://blog.csdn.net/lmj623565791/article/details/4791108...
    測天測地測空氣閱讀 1,500評論 1 6
  • 笑來老師在得到專欄《通往財富自由之路》中對財富自由的定義是:所謂財富自由,就是一個人不再為了生活開銷而出售自己的時...
    漫漫長路_閱讀 342評論 1 1
  • 六年級的時候,我突然發(fā)現(xiàn),我好像喜歡上了班里一個女生,那個女生很漂亮,也很酷,她畫畫很好看,也是她,讓我第一次了解...
    豚肩不掩豆閱讀 232評論 0 0
  • 歷史不容忘!寫在甲午戰(zhàn)爭123周年。 甲午戰(zhàn)爭祭 文||與你相識 那一聲炮響 民族的尊嚴落地 中華歷史上貼滿恥辱 ...
    與你相識_40fa閱讀 265評論 3 5

友情鏈接更多精彩內容