Kotlin Coroutine + retrofit + Okhttp3 网络请求实战篇

背景

  • 最近看到很多项目都将RxJava + Retrofit 替换成了 Coroutine + retrofit,首先Coroutine学习成本相对于Rxjava来说较低,而且最重要的一点是Kotlin的下实现线程切换的代码更加精简,逻辑相对更加清晰一些

注意:没有学习过DSL 以及 协程(此次实践将会使用) 的可以阅读以下两篇

Kotlin DSL
Kotlin 协程

封装RxJava + Retrofit + OkHttp3网络请求框架

网络层设计

在这里插入图片描述

1.首先添加以下开源库的依赖
"retrofit"                   : "com.squareup.retrofit2:retrofit:$retrofit_version",
"retrofit-converter-gson"    : "com.squareup.retrofit2:converter-gson:${retrofit_version}",
"retrofit-adapter-rxjava2"   : "com.squareup.retrofit2:adapter-rxjava2:${retrofit_version}",
"okhttp3"                    : "com.squareup.okhttp3:okhttp:${okhttp_version}",
"okhttp3-logging-interceptor": "com.squareup.okhttp3:logging-interceptor:${okhttp_version}",
"rxkotlin"                   : "io.reactivex.rxjava2:rxkotlin:$rx_kotlin_version",
"rxandroid"                  : "io.reactivex.rxjava2:rxandroid:$rx_android_version",
2.创建RetrofitFactory类

class RetrofitFactory private constructor() {
    private val retrofit : Retrofit

    fun <T> create(clazz: Class<T>) : T {
        return retrofit.create(clazz)
    }

    init {
        retrofit = Retrofit.Builder()
            .baseUrl(Constant.BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(initOkHttpClient())
            .build()
    }

    companion object {
        val instance by lazy {
            RetrofitFactory()
        }
    }

    private fun initOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor() // 添加自定义拦截器
            .connectTimeout(30, TimeUnit.SECONDS) // 请求超时时间 
            .writeTimeout(30, TimeUnit.SECONDS) // 写入超时时间
            .readTimeout(30, TimeUnit.SECONDS) // 读取超时时间
            .build()
    }
}
3.创建api接口类
/** @GET GET请求方式
@POST POST请求方式
@Query GET请求参数
@Header用来添加Header请求头
@FormUrlEncoded post请求头标示
其他注解请求方式:
@PUT 表示这是一个PUT请求
@DELETE 表示这是一个DELETE请求
@HEAD 表示这是一个HEAD请求
@OPTIONS 表示这是一个OPTION请求
@PATCH 表示这是一个PAT请求
**/

interface ApiService {
    @GET("/banner/json")
fun loadBanner(): Observable<BaseResponse<List<BannerResponse>>>
}
4.创建仓库类作为统一封装入口
class HomeRepository (loadState : MutableLiveData<State>) : ArticleRepository(loadState) {
    fun loadBanner(liveData: MutableLiveData<BaseResponse<List<BannerResponse>>>) {
    apiService.loadBanner()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            BaseObserver(
                liveData,
                loadState,
                this
            )
        )
    }
}
  • BaseObserver是对返回结果的处理
5.在ViewModel中对数据进行管理
class HomeViewModel(application: Application) :
    ArticleViewModel<HomeRepository>(application) {
    val mBannerData: MutableLiveData<BaseResponse<List<BannerResponse>>> = MutableLiveData()
    fun loadBanner() {
        mRepository.loadBanner(mBannerData)
    }
}
6.在Activity或者Fragment中对ViewModel中的数据进行观察即可

封装 Coroutine + Retrofit + OkHttp3网络请求框架

1.改写api接口类
// 使用suspend函数修饰
@GET("/banner/json")
suspend fun loadBannerCo() : BaseResponse<List<BannerResponse>>
2.使用DSL封装数据解析类
  • 不使用RxJava所以对返回的数据处理就不能使用BaseObserver
  • 所以在repository中调用apiServer的方法后需要将返回的数据做状态处理,为了简洁我使用DSL封装dataConvert数据解析类
fun <T> BaseResponse<T>.dataConvert(
    loadState: MutableLiveData<State>
) : T{
    when (errorCode) {
        ...
    }
}
3.修改仓库类
// 没有使用LiveData的postValue将数据传出,所以采用返回值的形式返回数据
suspend fun loadBannerCo() : List<BannerResponse> {
    return apiService.loadBannerCo().dataConvert(loadState)
}
4.修改ViewModel
// 作为返回值的接收值,在Activity或者Fragment中观察该值即可
var mBannerData: MutableLiveData<List<BannerResponse>> = 
MutableLiveData() 
fun loadBannerCo() {
    // 开启协程
    viewModelScope.launch {
        try{
            // 切换IO线程做数据请求
            val data = withContext(Dispatchers.IO) {
                mRepository.loadBannerCo()
            }
            // 设置LiveData即可
            mBannerData.value = data
        } catch (e : Exception) {
            e.printStackTrace()
        }
    }
}

  • 之后在Activity或者Fragment中对数据进行展示即可
项目Demo欢迎大家提出宝贵的意见
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页