retrofit2网络请求的kotlin版本封装

2024-06-05 12:08

本文主要是介绍retrofit2网络请求的kotlin版本封装,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

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

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

class CommonHttp {companion object {lateinit var mBaseUrl: Stringlateinit var retrofit: Retrofitlateinit var client:OkHttpClientlateinit var callBack:(back:HttpMessage)->Unit;}/*** 不使用拦截器的构造方法*/constructor(baseUrl:String,function:(back:HttpMessage)->Unit){callBack=functionmBaseUrl=baseUrlif(retrofit==null) {var httpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()var dispatcher = Dispatcher()dispatcher.maxRequests = 128dispatcher.maxRequestsPerHost = 32httpBuilder.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=functionmBaseUrl=baseUrlif(retrofit==null) {var httpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()var dispatcher = Dispatcher()dispatcher.maxRequests = 128dispatcher.maxRequestsPerHost = 32httpBuilder.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<ResponseBody>? = nullvar cookies:HashMap<String,String> = HashMap()when(objects.size){1->{var url=objects[0] as Stringcall= retrofit.create(CommonHttpService::class.java).get(url)}2->{var url=objects[0] as Stringvar params=objects[1] as HashMap<String,String>/*** 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 Stringvar params=objects[1] as HashMap<String,String>var files=objects[2] as HashMap<String, File>/*** 复合表单格式,适合同时提交参数与文件*/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<ResponseBody> {override fun onResponse(call: Call<ResponseBody>,response: retrofit2.Response<ResponseBody>,) {Log.e("http","请求成功")if(response!=null) {var message = Message()message.obj = responsemessage.what=0handler.sendMessage(message)}else{handler.sendEmptyMessage(-1)}}override fun onFailure(call: Call<ResponseBody>, 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<ResponseBody>var result=response.body().toString()var resultFormat=getResultFormat(result)when(msg.what){-1->{httpmsg.type=-1callBack(httpmsg)}0->{when(response.code()){200-> {httpmsg.code = resultFormat.code/*** 业务逻辑层面判断成功与失败*/if(resultFormat.code==1000) {httpmsg.type=0httpmsg.msg = resultFormat.msghttpmsg.result = result}else{httpmsg.type=1httpmsg.msg = resultFormat.msghttpmsg.result = result}}500,400,404->{httpmsg.type=-1httpmsg.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<String,String>,@Body body:RequestBody): Call<ResponseBody>@HTTP(method = "GET", hasBody = false)operator fun get(@Url url: String?): Call<ResponseBody>@HTTP(method = "GET", hasBody = false)operator fun get(@Url url: String?,@HeaderMap tokens: HashMap<String?, String?>?): Call<ResponseBody>@Multipart@HTTP(method = "POST", path = "{url}", hasBody = true)fun postFile(@Path(value = "url", encoded = true) url: String?,@Part parts: List<MultipartBody.Part?>?): Call<ResponseBody>@Multipart@HTTP(method = "POST", path = "{url}", hasBody = true)fun postFile(@Path(value = "url", encoded = true) url: String?,@Header("Cookie") token: String?,@Part parts: List<MultipartBody.Part?>?): Call<ResponseBody>
}

 

这篇关于retrofit2网络请求的kotlin版本封装的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033011

相关文章

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

conda安装GPU版pytorch默认却是cpu版本

《conda安装GPU版pytorch默认却是cpu版本》本文主要介绍了遇到Conda安装PyTorchGPU版本却默认安装CPU的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、问题描述二、网上解决方案罗列【此节为反面方案罗列!!!】三、发现的根本原因[独家]3.1 p

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧

IIS 7.0 及更高版本中的 FTP 状态代码

《IIS7.0及更高版本中的FTP状态代码》本文介绍IIS7.0中的FTP状态代码,方便大家在使用iis中发现ftp的问题... 简介尝试使用 FTP 访问运行 Internet Information Services (IIS) 7.0 或更高版本的服务器上的内容时,IIS 将返回指示响应状态的数字代

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1