Kotlin Coroutine + retrofit + Okhttp3 替換 RxJava2 + 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{
// 將BaseObserver中的數據處理做相應的比那花即可
}
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,如果有幫助留下一個star叭~ ,歡迎大家提出寶貴的意見
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章