Kotlin + 協程 + Retrofit + MVVM優雅的實現網絡請求

前言

最近一直閉關修煉Kotlin,說實話真香真好用,剛好公司準備交給我一個新項目,於是打算直接用Kotlin來構建項目。剛好整體架構搭建完畢了,於是把網絡請求這一部分先分享給大家。這次使用到的是 協程+ retrofit +mvvm的模式,我這兒直接用一個簡單的demo來看一下具體的實現方式吧。文章只是描述實現思路,需要demo的直接跳到文末

項目配置

首先先引入所需要的依賴
implementation 'android.arch.lifecycle:extensions:1.1.1' //協程 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1' //retrofit + okHttp3 implementation 'com.squareup.retrofit2:retrofit:2.4.0' implementation 'com.squareup.retrofit2:converter-gson:2.4.0' implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
實現思路
不管設計模式這些,先來一個簡單的網絡請求,就retrofit的基本實現,看看需要哪些步驟
1.創建retrofit

~~~
    val retrofit = Retrofit.Builder()
                .baseUrl(RetrofitClient.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(CoroutineCallAdapterFactory())
                .build()
~~~

2.創建service接口

    interface RequestService {
        @GET("wxarticle/chapters/json")
        fun getDatas() : Call<DataBean>
    }

3.發起請求

    val service = retrofit.create(RequestService::class.java)
    service.getDatas().enqueue(object : Callback<DataBean> {
        override fun onFailure(call: retrofit2.Call<DataBean>, t: Throwable) {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
        override fun onResponse(call: retrofit2.Call<DataBean>, response: Response<DataBean>) {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
    })

這只是描述了一個retrofit的簡單請求方式,實際項目中基本上都會封裝之後再使用,也爲了提高代碼的可讀性,降低各部分的耦合性,
通俗點來說,只有各司其職才能把工作幹好嘛,接下來咱們就圍繞着各司其職來一個一個實現

協程實現

接下來把上面的請求換成協程的方式來實現
1.創建RetrofitClient
object爲了使RetrofitClient 只能有一個實例

    object RetrofitClient {
        val BASE_URL =  "https://wanandroid.com/"
        val reqApi by lazy {
            val retrofit = Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(CoroutineCallAdapterFactory())
                    .build()
            return@lazy retrofit.create(RequestService::class.java)
        }
    }

2.創建service接口類

interface RequestService {
    @GET("wxarticle/chapters/json")
    fun getDatas() : Deferred<DataBean>
}

因爲我們後續會使用到協程,所以這兒將Call換成了Deferred
3.發起請求

    GlobalScope.launch(Dispatchers.Main) {
        withContext(Dispatchers.IO){
          val dataBean = RetrofitClient.reqApi.getDatas().await()
        }
        //更新ui
    }

上面用到了協程,這兒只講述他的應用了,具體的移步官方文檔進一步瞭解。
網絡請求在協程中,並且在IO調度單元,所以不用擔會阻塞主線程
分享我的一個Android的學習交流羣:騰訊@Android高級架構:818520403

協程 + ViewModel + LiveData實現

上面也只是簡單的實現,只不過是換成了協程,在項目中,還可以進一步封裝,方便使用前面也提到了MVVM,所以還用到了Android 新引入的組件架構之ViewModel和LiveData,先看ViewModel的實現

class ScrollingViewModel  : ViewModel() {
    private val TAG = ScrollingViewModel::class.java.simpleName
    private val datas: MutableLiveData<DataBean> by lazy { MutableLiveData<DataBean>().also { loadDatas() } }
    private val repository = ArticleRepository()
    fun getActicle(): LiveData<DataBean> {
        return datas
    }
    private fun loadDatas() {
        GlobalScope.launch(Dispatchers.Main) {
            getData()
        }
        // Do an asynchronous operation to fetch users.
    }
    private suspend fun getData() {
        val result = withContext(Dispatchers.IO){
//            delay(10000)
            repository.getDatas()
        }
       datas.value = result
    }
}

ViewModel將作爲View與數據的中間人,Repository專職數據獲取,下面看一下Repository的代碼,用來發起網絡請求獲取數據

 class ArticleRepository {
     suspend fun getDatas(): DataBean {
          return RetrofitClient.reqApi.getDatas().await()
      }
  }
在Activity中代碼如下
    private fun initData() {
        model.getActicle().observe(this, Observer{
            //獲取到數據
            toolbar.setBackgroundColor(Color.RED)
        })
    }

結語

通過上面只是描述了一個簡單的網絡請求協程的實現過程,在項目中我還做了進一步的封裝,將幾個需要重複創建的類封裝了一下,基本上能滿足大部分的需求要是感興趣的小夥伴,可以下載demo參考一下,同時秉持一貫謙虛的風格希望各位大佬能指出不當的地方,深表感謝

附上項目地址

github.com/qingtian521…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章