private val repository by lazy { WxArticleRepository() }
val wxArticleLiveData = StateLiveData<List>()
fun requestNet() {
viewModelScope.launch {
repository.fetchWxArticle(wxArticleLiveData)
}
}
}
很简单,引入对应的数据仓库Repo,然后使用协程执行网络请求方法。来看下Repo中的代码。
Repository中代码示例
class WxArticleRepository : BaseRepository() {
private val mService by lazy { RetrofitClient.service }
suspend fun fetchWxArticle(stateLiveData: StateLiveData<List>) {
executeResp(stateLiveData, mService::getWxArticle)
}
}
interface ApiService {
@GET(“wxarticle/chapters/json”)
suspend fun getWxArticle(): BaseResponse<List>
}
获取一个Retrofit实例,然后调用ApiService
接口方法。
封装一的优势
======
-
代码很简洁,不需要手写线程切换代码,没有很多的接口回调。
-
自带Loading状态,不需要手动启用Loading和关闭Loading。
-
数据驱动ui,以LiveData为载体,将页面状态和网络结果通过在LiveData返回给ui。
封装一的不足
======
封装一的核心思想是:一个LiveData贯穿整个网络请求链。这是它的优势,也是它的劣势。
-
解耦不彻底,违背了"在应用的各个模块之间设定明确定义的职责界限"的思想
-
LiveData监听时,如果需要Loading,
BaseActivity
都需要实现带有Loading方法接口。 -
obserState()
方法第二个参数中传入了UI引用。 -
不能达到"看方法如其意",如果是刚接触,会有很多疑问:为什么需要一个livedata作为方法的参数。网络请求的返回值去哪了?
-
封装一还有一个最大的缺陷:对于是多数据源,封装一就展示了很不友好的一面。
Repository是做一个数据仓库,项目中获取数据的方式都在这里同意管理,网络获取数据只是其中一个方式而已。
如果想加一个从数据库或者缓存中获取数据,封装一想改都不好改,如果强制改就破坏了封装,侵入性很大。
针对封装一的不足,优化出了封装二。
二、封装二
=====
思路
–
-
想要解决上面的不足,不能以LiveData为载体贯穿整个网络请求。
-
Observe()
方法中去掉ui引用,不要小看一个ui引用,这个引用代表着具体的Activity
跟Observe
耦合起来了,并且Activity
还要实现IUiView
接口。 -
网络请求跟Loading状态分开了,需要手动控制Loading。
-
Repository中的方法都有返回值,