从最早网络请求使用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<ResponseBody>? = null
var cookies:HashMap<String,String> = 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<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 String
var 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 = response
message.what=0
handler.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=-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<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>
}
版权声明:本文为u011334510原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。