前言
最近一直闭关修炼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参考一下,同时秉持一贯谦虚的风格希望各位大佬能指出不当的地方,深表感谢
网友评论