retrofit2网络请求的kotlin版本封装
发布日期:2021-05-08 17:48:49 浏览次数:14 分类:精选文章

本文共 7298 字,大约阅读时间需要 24 分钟。

从最早网络请求使用httpclient开始,到后面只用okhttp, 到使用retrofit2 ,(听闻retrofit2有kotlin版本,但是我去官网看似乎仍然是java 的)

虽然网络框架还是基于java的。但是多数项目都开始使用kotlin编写。所以对自己之前的封装的网络框架也使用kotlin重构一下吧。

其实还有一些变化,在测试版本的as中 ,权限请求的方法也过时了,结构变得更灵活,所以以后会把那个再重新封装一下。

常规的app用的最多的感觉就是访问网络和权限请求了。好了就这些,这次的封装还耐心的写了注解,并且补全了复合数据的提交。哈哈希望看了这篇的能有点收获吧

有些业务逻辑相关的部分简写了,可以根据实际去扩展。下面是主要代码,其实有部分还没有完善,等再有时间会整理一下。发布到github的仓库。

class CommonHttp {    companion object {        lateinit var mBaseUrl: String        lateinit var retrofit: Retrofit        lateinit var client:OkHttpClient        lateinit var callBack:(back:HttpMessage)->Unit;    }    /**     * 不使用拦截器的构造方法     */    constructor(baseUrl:String,function:(back:HttpMessage)->Unit){        callBack=function        mBaseUrl=baseUrl        if(retrofit==null) {            var httpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()            var dispatcher = Dispatcher()            dispatcher.maxRequests = 128            dispatcher.maxRequestsPerHost = 32            httpBuilder.dispatcher(dispatcher)            httpBuilder.connectionPool(ConnectionPool(32, 20, TimeUnit.MILLISECONDS))            client =                httpBuilder.readTimeout(3, TimeUnit                    .MINUTES).connectTimeout(3, TimeUnit.MINUTES)                    .writeTimeout(                        3,                        TimeUnit.MINUTES                    ).build()            retrofit = Retrofit.Builder().baseUrl(baseUrl).client(client).build();        }    }    /**     * 带拦截器的构造方法。多个域名的情况可以考虑使用     */    constructor(baseUrl:String,interceptor: Interceptor,function:(back:HttpMessage)->Unit){        callBack=function        mBaseUrl=baseUrl        if(retrofit==null) {            var httpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()            var dispatcher = Dispatcher()            dispatcher.maxRequests = 128            dispatcher.maxRequestsPerHost = 32            httpBuilder.dispatcher(dispatcher)            httpBuilder.connectionPool(ConnectionPool(32, 20, TimeUnit.MILLISECONDS))            client =                httpBuilder.readTimeout(3, TimeUnit.MINUTES).connectTimeout(3, TimeUnit.MINUTES)                    .writeTimeout(                        3,                        TimeUnit.MINUTES                    ).addInterceptor( if (interceptor==null) BaseUrlInterceptor() else interceptor).build()                retrofit = Retrofit.Builder().baseUrl(baseUrl).client(client).build();        }    }    fun doRequest(vararg objects:Any){        var call:Call
? = null var cookies:HashMap
= HashMap() when(objects.size){ 1->{ var url=objects[0] as String call= retrofit.create(CommonHttpService::class.java).get(url) } 2->{ var url=objects[0] as String var params=objects[1] as HashMap
/** * json 形式 */ var jsonBody:RequestBody= RequestBody.create(MediaType.parse("application/json;charset=utf-8"), JSON.toJSONString(params)) /** * form 表单格式 */ var formBodyBuilder=FormBody.Builder() for(param in params){ formBodyBuilder.add(param.key,param.value) } var formBody=formBodyBuilder.build() call= retrofit.create(CommonHttpService::class.java).post(url,params,jsonBody)//json 或表单形式提交 } 3->{ var url=objects[0] as String var params=objects[1] as HashMap
var files=objects[2] as HashMap
/** * 复合表单格式,适合同时提交参数与文件 */ var builer=MultipartBody.Builder() for(param in params){ builer.addFormDataPart(param.key,param.value) } for(file in files){ var requestBody=RequestBody.create(MediaType.parse("application/octet-stream"),file.value) builer.addFormDataPart(file.key,file.value.name,requestBody) } var multipartBody=builer.build() call= retrofit.create(CommonHttpService::class.java).postFile(url,multipartBody.parts())// call= retrofit.create(CommonHttpService::class.java).post(url,cookies,multipartBody)//不同的请求格式,两种都可以,看服务器接收格式 } } call?.enqueue(object: retrofit2.Callback
{ override fun onResponse( call: Call
, response: retrofit2.Response
, ) { Log.e("http","请求成功") if(response!=null) { var message = Message() message.obj = response message.what=0 handler.sendMessage(message) }else { handler.sendEmptyMessage(-1) } } override fun onFailure(call: Call
, t: Throwable) { Log.e("http","请求异常") handler.sendEmptyMessage(-1) } }) } /** * httpmsg type 0成功 1失败 -1异常。指代服务器返回结果,-1访问失败 使用 * code 指代服务器业务逻辑返回码 * result 返回的数据 */ var handler= object:Handler(Looper.getMainLooper()){ override fun handleMessage(msg: Message) { super.handleMessage(msg) var httpmsg=HttpMessage() var response=msg.obj as retrofit2.Response
var result=response.body().toString() var resultFormat=getResultFormat(result) when(msg.what){ -1->{ httpmsg.type=-1 callBack(httpmsg) } 0->{ when(response.code()){ 200-> { httpmsg.code = resultFormat.code /** * 业务逻辑层面判断成功与失败 */ if(resultFormat.code==1000) { httpmsg.type=0 httpmsg.msg = resultFormat.msg httpmsg.result = result }else{ httpmsg.type=1 httpmsg.msg = resultFormat.msg httpmsg.result = result } } 500,400,404->{ httpmsg.type=-1 httpmsg.code=response.code() } } callBack(httpmsg) } } } } fun getResultFormat(json:String):ResultFormat{ return JSON.parse(json) as ResultFormat } /** * 默认拦截器。在baseurl改变时进行重定向 */ class BaseUrlInterceptor:Interceptor{ open override fun intercept(chain: Interceptor.Chain): Response { var request:Request=chain.request() var oldHttpUrl:HttpUrl=request.url() var builder:Request.Builder=request.newBuilder() var newHttpUrl:HttpUrl= HttpUrl.parse(mBaseUrl)!! var httpUrl=oldHttpUrl.newBuilder().scheme(newHttpUrl.scheme()). host(newHttpUrl.host()).port(newHttpUrl.port()).build() return chain.proceed(builder.url(httpUrl).build()) } }}data class ResultFormat(var msg:String,var code:Int)data class HttpMessage(var type:Int=-1,var code:Int=-1,var msg:String="",var result:String="")
interface CommonHttpService {    @HTTP(method="POST",path="{url}",hasBody=true)    @Headers("ContentType:application/json;charset=UTF-8")    fun post(@Path(value="url",encoded = true) url:String?,@HeaderMap() cookies:HashMap
,@Body body:RequestBody): Call
@HTTP(method = "GET", hasBody = false) operator fun get(@Url url: String?): Call
@HTTP(method = "GET", hasBody = false) operator fun get( @Url url: String?, @HeaderMap tokens: HashMap
? ): Call
@Multipart @HTTP(method = "POST", path = "{url}", hasBody = true) fun postFile( @Path(value = "url", encoded = true) url: String?, @Part parts: List
? ): Call
@Multipart @HTTP(method = "POST", path = "{url}", hasBody = true) fun postFile( @Path(value = "url", encoded = true) url: String?, @Header("Cookie") token: String?, @Part parts: List
? ): Call
}

 

上一篇:android拖拽控件
下一篇:关于socket 两台Android设备上的通信

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2025年03月25日 15时04分43秒