前言
好久没有写博客了,笔者最近也是比较忙。刚刚换了工作,刚刚入职一个月,唉,周末还要回家去,一直没时间写博客,今天终于还是抽时间将这个博客给发出来了。
关于网络请求。大家了解的 无非就是 okhttp, retrofit2 这些大厂出来的框架。用起来顺手,很多人包括笔者都会在自己加上一层封装。主要是为了自己项目中使用方便。
kotlin 已经出来很久了。相信大家都用的比较熟悉。笔者今天带来的就是 协程+ Retrofit 进行封装的网络请求框架。
基础使用
现在人都急性子。先给大家看看使用是一个get 请求的样子。首先是配置。笔者这里使用DSL风格去配置基础的信息等。也是方便哈。
private val moya by lazy {
moya(this) {
url = "https://www.wanandroid.com"
retry = true
time = {
connect = 10L
write = 10L
read = 10L
}
cache = {
type = CacheType.NONE
path = ""
size = 10
noNetworkTimeOut = 10
networkTimeOut = 10
}
head = {
put("hello", "world")
}
log = {
level = LoggerLevel.BASIC
interceptors = setOf(object : OnLogInterceptor {
override fun onLogInterceptorInfo(message: String) {
}
})
}
adapter = {}
converter = {}
cookie = {}
}
}
复制代码
然后就是使用。简单的get 请求。
viewModel.viewModelScope.launch {
moya.create()
.parameter("username", "moya")
.parameter("password", "123456")
.parameter("repassword", "123456")
.doPost<RegisterData>("user/register")
.doComplete { hideLoadDialog() }
.doFailed { showRequestDialog(it.message ?: " is empty ") }
.doSuccess { showRequestDialog(it.toString()) }
}
复制代码
设计思路
其实还是想将自己这次封装的心得分享给大家。先给大家看一下项目的架构
- 使用了插件作为依赖管理
这么干主要还是为了方便。这种方式在我忘记在哪看到的了。不过觉得其实还行。比BuildSrc
方便一点。
- 项目分成了基础模块和协程模块
这里就为了拓展。想着以后还要将RxJava那套加进来。所以很多核心的功能都放在了moya中。
- 协程的拓展功能都使用Kotlin 的拓展函数去完成
主要还是一个字。香!
关于配置
这个就简单了。主要就使用了构造者模式去创建一个对象。笔者遇到的坑就是关于 DSL 部分。如果能够实现我在上面实现的那种方式。以网络超时为例。
// 配置网络超时时间等
var Moya.Builder.time: NetWorkTimeOut.() -> Unit by LambdaDelegate<NetWorkTimeOut, Moya.Builder>(
NetWorkTimeOut()
) { netWorkTime, builder ->
builder.connectTimeout(time = netWorkTime.connect)
builder.readTimeout(time = netWorkTime.read)
builder.writeTimeout(time = netWorkTime.write)
}
复制代码
其核心代码就这么几行。这么看有点意思吧,当然用到了拓展函数还有委托。 就能够实现 time{}
的效果,为了控制作用域笔者还是用了DslMarker
去控制他。
动态修改url
其实这个需求很少遇到,不过遇到了,之前看到有人创建了多个 retrofit对象去控制,不好啊。其实可以是用拦截器控制的。笔者这里也直接写好了。只需要在请求中加入下面的代码就能够动态替换url
baseUrl("new host url")
复制代码
原理嘛,就是拦截器,放上核心代码,详细的可以去看源码哈。
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val headers = request.headers
if (headers.size > 0) {
val url = headers[DynamicHeard.DYNAMIC_URL]
if (url != null) {
val httpUrl = request.url
val newBuilder = httpUrl.newBuilder()
checkBaseUrl(url, newBuilder)
setNewHost(url, newBuilder)
request = request.newBuilder()
.removeHeader(DynamicHeard.DYNAMIC_URL)
.url(newBuilder.build())
.build()
return chain.proceed(request)
}
}
return chain.proceed(request)
}
复制代码
动态修改请求超时
其实也是一个比较小众的需求。依然可以通过拦截器去触发。笔者这里也写好了 connectTimeOut
在请求中加入下面代码就能配置请求超时时间啦。方便哈
.connectTimeOut(1)
复制代码
最后
写这个小框架,笔者也学习了很多,对kotiln 的理解也更佳深了,项目中放在了 moya 有兴趣的读者可以自行学习哈。
最后的最后。新工作有点小累,也发现了自己的很多不足。期待更上一成楼。