Kotlin okhttp 简单封装

第一次写博客,感觉还是有点的小激动。
主要对自己开始学习Kotlin的过程做个记录,毕竟好记性不如烂笔头。虽然我一直都没有做到,这可能是个开始。
依赖的添加:

 implementation 'com.squareup.okhttp3:okhttp:3.1.2'
 implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.60'
 // 这里有一个大坑啊。fastjson版本不是1.2.36和1.1.61是不支持Kotlin的。希望官网是早日更新
 implementation 'com.alibaba:fastjson:1.2.36'
 implementation 'com.alibaba:fastjson:1.1.61.android'

首先是对okhttp的封装

import okhttp3.Interceptor
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit

class HttpManager private constructor() {

    var httpClient: OkHttpClient? = null
    val timeUnit: TimeUnit = TimeUnit.SECONDS
    val connectTimeOut: Long = 10
    val readTimeOut: Long = 10
    val writeTimeOut: Long = 10
    var interceptors: ArrayList<Interceptor> = ArrayList()
    var networkInterceptors: ArrayList<Interceptor> = ArrayList()

    companion object {
        fun instace() = Holder.INSTACE
    }

    private object Holder {
        val INSTACE = HttpManager()

        init {
            INSTACE.initHttpClient()
        }
    }

    fun initHttpClient(): OkHttpClient? {
        var builder = OkHttpClient.Builder()
                .connectTimeout(connectTimeOut, timeUnit)
                .readTimeout(readTimeOut, timeUnit)
                .writeTimeout(writeTimeOut, timeUnit)
        builder = initInterceptor(builder, interceptors)
        builder = initNetworkInterceptor(builder, networkInterceptors)
        httpClient = builder.build()
        return httpClient
    }

    fun addInterceptor(interceptors: ArrayList<Interceptor>) {
        this.interceptors = interceptors
    }

    fun addNetworkInterceptor(interceptors: ArrayList<Interceptor>) {
        this.networkInterceptors = interceptors
    }

    fun initInterceptor(builder: OkHttpClient.Builder?, interceptors: ArrayList<Interceptor>?): OkHttpClient.Builder? {
        interceptors?.forEach { i: Interceptor? ->
            if (i != null)
                builder?.addInterceptor(i)
        }
        return builder
    }

    fun initNetworkInterceptor(builder: OkHttpClient.Builder?, networkInterceptors: ArrayList<Interceptor>?): OkHttpClient.Builder? {
        networkInterceptors?.forEach { i: Interceptor? ->
            if (i != null)
                builder?.addNetworkInterceptor(i)
        }
        return builder
    }

}

okhttp封装好了后就可以对请求rquest进行封装了

import com.base.http.callback.AbstractCallback
import okhttp3.*
import java.io.IOException

class RequestManager {

    var okHttpClient: OkHttpClient? = null
    var builder: Request.Builder? = null

    init {
        builder = Request.Builder()
    }

    constructor() {
        okHttpClient = HttpManager.instace().httpClient
    }

    constructor(okHttpClient: OkHttpClient?) {
        if (okHttpClient == null)
            RequestManager()
        else
            this.okHttpClient = okHttpClient
    }

    fun doGet(url: String, headers: HashMap<String, String>? = null, params: HashMap<String, String>? = null): RequestManager {
        if (url.isBlank())
            return this
        if (headers != null)
            addHeaders(headers)
        builder!!.url(if (params != null) setGetParams(url, params) else url).get()
        return this
    }

    fun doPost(url: String, headers: HashMap<String, String>? = null, params: HashMap<String, String>? = null): RequestManager {
        if (url.isBlank())
            return this
        if (headers != null)
            addHeaders(headers)
        builder!!.url(url)
        builder!!.post(setPostParams(params))
        return this
    }

    fun addHeaders(headers: HashMap<String, String>) {
        headers.entries.forEach { entry ->
            headers.keys
            builder?.addHeader(entry.key, entry.value)
        }
    }

    fun setGetParams(url: String, params: HashMap<String, String>): String {
        var sb = StringBuilder(url)
        if (params.isNotEmpty()) sb.append("?") else sb
        params.forEach { entry ->
            params.keys
            sb.append(entry.key + "=" + entry.value + "&")
        }
        return if (sb.toString().endsWith("&")) sb.subSequence(0, sb.lastIndex).toString() else sb.toString()
    }

    fun setPostParams(params: HashMap<String, String>?): RequestBody? {
        var builder = FormBody.Builder()
        params?.forEach { entry ->
            params.keys
            builder.add(entry.key, entry.value)
        }
        return builder.build()
    }

    fun execute(abstractCallback: AbstractCallback) {
        okHttpClient!!.newCall(builder!!.build())?.enqueue(object : Callback {
            override fun onResponse(call: Call?, response: Response) {
                abstractCallback.succeed(call, response)
            }

            override fun onFailure(call: Call?, e: IOException?) {
                abstractCallback.failed(call, e)
            }
        })
    }
}

请求封装好了后就可以对我们的回调进行统一处理了。首先是定义了一个抽象的回调类当然接口也是没有问题的

import okhttp3.Call
import okhttp3.Response
import java.lang.Exception

abstract class AbstractCallback{
    abstract fun succeed(call: Call?, response: Response)

    abstract fun failed(call: Call?, e: Exception?)
}

定义好基类的抽象回调后我们可继承它来对我们的数据进行一些处理了。如返回string数据

import android.util.Log
import okhttp3.Call
import okhttp3.Response
import java.io.IOException

abstract class BasicCallback : AbstractCallback() {
    val TAG = BasicCallback::class.java.simpleName
    abstract fun succeed(call: Call?, result: String)

    override fun succeed(call: Call?, response: Response) {
        try {
            if (call!!.isCanceled()) {
                failed(call, IOException("Canceled!"))
                return
            }
            Log.e(TAG, "request:" + call.request().toString())
            Log.e(TAG, "response:" + response.toString())
            if (response.code() !in 200..299) { // 返回Code不在200-299请求失败
                failed(call, IOException("request failed , reponse's code is : " + response.code()))
                return
            }
            val str = response.body()!!.string()
            Log.e(TAG, str)
            succeed(call, str)
        } catch (e: Exception) {
            Log.e(TAG, e.toString() + "")
            failed(call, e)
        } finally {
            if (response.body() != null)
                response.body()!!.close()
        }
    }

}

由于服务器一般返回JSON数据所以我封装了个直接返回对象的回调,我在这使用的fastjson。
fastjson解析对象方法

class JsonParser {

    companion object {
        fun <T> parserToBean(jsonStr: String, clz: Class<T>) : T {
            return JSON.parseObject(jsonStr,clz)
        }
}

返回对象回调类定义

import android.util.Log
import com.base.http.parser.JsonParser
import okhttp3.Call
import okhttp3.Response
import java.io.IOException

abstract class JsonCallback<T>(var clz: Class<T>) : AbstractCallback() {

    val TAG = JsonCallback::class.java.simpleName

    abstract fun succeed(call: Call?, data: T)

    override fun succeed(call: Call?, response: Response) {
        try {
            if (call!!.isCanceled()) {
                failed(call, IOException("Canceled!"))
                return
            }
            Log.e(TAG,"request:" + call.request().toString())
            Log.e(TAG,"response:" + response.toString())
            if (response.code() !in 200..299) {
                failed(call, IOException("request failed , reponse's code is : " + response.code()))
                return
            }
            val str = response.body()!!.string()
            Log.e(TAG,str)
            succeed(call, JsonParser.parserToBean(str, clz))
        } catch (e: Exception) {
            Log.e(TAG,e.toString() + "")
            failed(call, e)
        } finally {
            if (response.body() != null)
                response.body()!!.close()
        }
    }

}

写到这简单封装就写完了,只有post和get请求。文件的上传和下载还未添加。
最后就是使用了

fun sendRequest() {
    val params = HashMap<String, String>()
    params["key"] = "value"
    requestManager.doPost(url,header,params).execute(object:JsonCallback<Bean>(Bean::class.java) {
                override fun succeed(call: Call?, data: Bean) {
                    // data就是返回对象了

                }

                override fun failed(call: Call?, e: Exception?) {
                }

            })
        }

写完收工。文件的上传和下载呢?加油

猜你喜欢

转载自blog.csdn.net/caideqiang/article/details/81479164