最近在学习网易公开课,里面有很多大牛分享,这次代码基本是把学习视频代码重敲了一边,同时为了加强对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())
}
}
)
总结:
代码结构非常简单清晰,但这种思路非常重要,在项目中对代码的合理封装,业务的组件化抽取非常重要。