最近学习了Kotlin,感受就是好处太多了 欲罢不能,这其中协程这个特点处理异步非常不错,于是花了很长时间结合Retrofit封装了网络请求,感觉非常简洁好用。
准备工作:Retrofit的初始化 常规写法
引入第三方
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.2.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
复制代码
BaseResponse
class BaseResponse<T> {
val data: T? = null;
val errorCode: Int? = null;
val errorMsg: String? = null;
var exception: Exception? = null;
}
复制代码
Api接口
interface ApiInterface {
@GET("/article/listproject/0/json")
suspend fun getListProject(): BaseResponse<ListProjectBean?>
}
复制代码
初始化
使用顶层函数和懒加载初始化ApiInterface
val Api: ApiInterface by lazy {
Retrofit.Builder()
.baseUrl("https://www.wanandroid.com")
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpClient())
.build().create(ApiInterface::class.java)
}
private fun getOkHttpClient(): OkHttpClient {
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
.readTimeout(30, TimeUnit.SECONDS) //设置读取超时时间
.writeTimeout(30, TimeUnit.SECONDS) //设置写的超时时间
.connectTimeout(30, TimeUnit.SECONDS)
if (BuildConfig.DEBUG) {
val httpLoggingInterceptor = HttpLoggingInterceptor()
builder.addInterceptor(httpLoggingInterceptor.apply {
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
})
}
return builder.build()
}
复制代码
开始调用
一:最简单的调用
class MainVm : BaseViewModel() {
val responseText=ObservableField<String>("11111");
/**
* 请求网络
*/
fun requestData(){
viewModelScope.launch {
request {
getListProject();
}.next {
Log.e("data===>","data=====>${this.data}")
responseText.set(this.data.toString())
}
}
}
}
复制代码
所有请求都是再ViewModel中进行的,因为我使用了viewModelScope可以防止内存泄漏。调用起来是不是特别简洁
这里说明一下 viewModelScope.launch就是开启一个协程,不用多说,然后里面调用了request方法请求网络,这个方法我封装再BaseViewModel中。getListProject方法就是定义再ApiInterface 的网络接口,后面next方法就是请求成功的处理(next方法仿照kotlin的apply方法实现的), 之所以用next名称是因为之前一直再用Rxjava。然后调用的时候默认开启请求的对话框的。
二:关闭对话框的请求
class MainVm : BaseViewModel() {
val responseText=ObservableField<String>("11111");
/**
* 请求网络
*/
fun requestData(){
viewModelScope.launch {
request(false) {
getListProject();
}.next {
Log.e("data===>","data=====>${this.data}")
responseText.set(this.data.toString())
}
}
}
}
复制代码
request传入false即可,最后是不是还得加个获取异常,其实也很简单。
三:异常获取
class MainVm : BaseViewModel() {
val responseText=ObservableField<String>("11111");
/**
* 请求网络
*/
fun requestData(){
viewModelScope.launch {
request(false) {
getListProject();
}.next {
Log.e("data===>","data=====>${this.data}")
responseText.set(this.data.toString())
}.catchException {
when(this){
is ApiException->{
}
is IOException->{
}
else->{
}
}
}
}
}
}
复制代码
是不是超级简单,后面加上catchException 方法就获取到了所有的异常,当然request方法里面已经对异常统一处理了,不过demo里面统一处理为简单的土司
感觉这样封装调用起来真方便,这还得益于kotlin的lambda表达式 和带有接收者的函数的方便
详细的就不多说了 看demo吧,github地址:
欢迎提供意见建议
使用kotlin的flow封装见这篇文章