Android 无缝切换不同网络请求框架

最近在学习网易公开课,里面有很多大牛分享,这次代码基本是把学习视频代码重敲了一边,同时为了加强对kotlin语言使用,后期写代码都将切到kotlin语言。

最好的语言是用图来描述,所以我还是通过画图和代码来讲解一下原理。

架构介绍:

1.这个架构还是很简单的,如上图有一个公共接口IHttpProcess,里面只有一个post网络请求方法,该接口在HttpHelper,VolleyProcess,OkhttpProcess等类都来实现该方法。

interface IHttpprocessor{
    fun post(url : String,params : HashMap<String,Object>,callback : ICallBack)
}

2.HttpHelper是一个单例里面有一个IHttpProcess类对象,这种作为父类可以持有VolleyProcess,OkhttpProcess等不同框架类,

这里切换不同框架就是通过设置IHttpProcess类对象,如果要添加其它网络框架只有实现IHttpProcess接口即可。

class HttpHelper : IHttpprocessor{
    //具体网络框架实现类
    var mIHttpprocessor : IHttpprocessor? = null
    //单例
    companion object {
        private var instance : HttpHelper? = null
        get(){
            if(field == null){
                field = HttpHelper();
            }
            return field;
        }

        @Synchronized
        fun instance():HttpHelper{
            return instance!!
        }
    }
    
    //初始化设置网络框架
    fun init(httpPrecoss:IHttpprocessor){
        mIHttpprocessor = httpPrecoss
    }

    //调用网络请求方法
    override fun post(url: String, params: HashMap<String, Object>, callback: ICallBack) {
        //参数处理
        var finalUrl:String  = appendParams(url,params)
        //具体调用网络框架
        mIHttpprocessor?.post(finalUrl,params,callback)
    }

    private fun appendParams(url: String, params: HashMap<String, Object>):String {
        if(params == null || params.isEmpty()){
            return url
        }
        val stringBuild:StringBuilder = StringBuilder(url)
        if(stringBuild.indexOf("?") <= 0){
            stringBuild.append("?")
        }else{
            if(!stringBuild.toString().endsWith("?")){
                stringBuild.append("&")
            }
        }

        params.forEach {
            stringBuild.append("&"+it.key).append("=").append(encode(it.value.toString()))
        }
        Log.d("HttpHelper","url = " +stringBuild.toString())
        return stringBuild.toString()
    }

    private fun encode(str:String):String{
        return URLEncoder.encode(str,"utf-8")
    }

}

3.具体网络框架使用,下面我只用了VolleyProcess和OkhttpProcess两个框架代码很简单就是调用而已

OkhttpProcessle类

class OkHttpProcessor : IHttpprocessor{

    private var client : OkHttpClient? = null
    private var mHandler : Handler? = null
    constructor(){
        client = OkHttpClient()
        mHandler = Handler(Looper.getMainLooper())
    }

    override fun post(url: String, params: HashMap<String, Object>, callback: ICallBack) {
       val requstbody : RequestBody = appendBody(params)
       val request: Request? = Request.Builder().url(url).post(requstbody).build()
        client?.newCall(request)?.enqueue(object : Callback{
            override fun onFailure(call: Call, e: IOException) {
                callback?.onFail()
                e.printStackTrace()
            }

            override fun onResponse(call: Call, response: Response) {
                if(response.isSuccessful()){
                    val str : String = response.body()!!.string()
                    mHandler?.post(Runnable {
                        callback?.onSuncess(str)
                    })
                }
            }

        })
    }

    private fun appendBody(params: HashMap<String, Object>): RequestBody {
        val body : FormBody.Builder = FormBody.Builder()
        if(params == null || params.isEmpty()){
            return body.build();
        }
        params?.forEach(){
            body.add(it.key,it.value.toString())
        }
        return body.build()
    }

}

VolleyProcess类

class VolleyPorcess : IHttpprocessor {

    companion object {
        var mQueue:RequestQueue ? = null
    }

    constructor(context:Context){
        mQueue = Volley.newRequestQueue(context)
    }

    override fun post(url: String, params: HashMap<String, Object>, callback: ICallBack) {
        val stringRequest:StringRequest = StringRequest(Request.Method.POST,url,Response.Listener<String> {
            callback.onSuncess(it)
        },Response.ErrorListener{
            Log.d("VolleyPorcess",it.toString())
            callback.onFail()
        })
        mQueue?.add(stringRequest)
    }
}

4.初始化网络框架也是设置网络框架这个一句代码即可切换

class MyApplication : Application(){

    override fun onCreate() {
        super.onCreate()
        //HttpHelper.instance().init(OkHttpProcessor())//使用okhttp
        HttpHelper.instance().init(VolleyPorcess(this))//使用volley
    }
}

5.最后就是调用

 val params: HashMap<String, Object> = HashMap()
        params.put("province_id", 1 as Object)
        HttpHelper.instance().post(
                url,
                params,
                object : HttpCallBack<Response>() {

                    override fun onSucess(response: Response) {
                        Log.d(TAG,response.toString())
                    }
                }
        )

总结:

代码结构非常简单清晰,但这种思路非常重要,在项目中对代码的合理封装,业务的组件化抽取非常重要。

传送门

发布了92 篇原创文章 · 获赞 27 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/zhuxingchong/article/details/94382869