【发布时间】:2020-04-09 10:40:03
【问题描述】:
如何加入多个不同的 observable 并订阅 viewmodel?
我使用的是单一事实来源 原理,所以我首先从db获取数据,然后从webservice加载数据,最后将所有数据保存到db。
为此,我使用了 rxjava、room、dagger2、retrofit 库。但是出现了一些问题。我必须得到 来自网络服务的多个列表并将每个列表保存到数据库。我尝试了一些解决方案,但是这段代码 多次回复同一个请求。进度条每次都会改变。我怎样才能简化?最佳实践。
API.json
{
"data": {
"ad": [
{
"id": 11,
"image": "ad/ru/msG0y8vuXl.png"
}
...
],
"categories": [...],
"status": [...],
"location": [...]
}
}
HomeRepository.kt
class HomeRepository @Inject constructor(
private val indexApi: IndexApi,
private val categoryDao: CategoryDao,
private val userDao: UserDao,
private val adDao: AdDao
) {
fun getCategoryList(): Observable<List<Category>> {
val categoryListDb: Observable<List<Category>> = categoryDao.getCategoryList()
.filter { t: List<Category> -> t.isNotEmpty() }
.subscribeOn(Schedulers.computation())
.toObservable()
val categoryListApi: Observable<List<Category>> = indexApi.getIndex()
.toObservable()
.map { response ->
Observable.create { subscriber: ObservableEmitter<Any> ->
categoryDao.insertCategoryList(response.data.categories)
subscriber.onComplete()
}
.subscribeOn(Schedulers.computation())
.subscribe()
response.data.categories
}
.subscribeOn(Schedulers.io())
return Observable
.concatArrayEager(categoryListDb, categoryListApi)
.observeOn(AndroidSchedulers.mainThread())
}
fun getUserList(): Observable<List<User>> {
// same as above
}
fun getAdList(): Observable<List<Ad>> {
// same as above
}
}
HomeViewmodel.kt
class HomeViewModel @Inject constructor(
private val homeRepository: HomeRepository
) : BaseViewModel() {
private val categoryLiveData: MutableLiveData<Resource<List<Category>>> = MutableLiveData()
private val adLiveData: MutableLiveData<Resource<List<Ad>>> = MutableLiveData()
private val userLiveData: MutableLiveData<Resource<List<User>>> = MutableLiveData()
fun categoryResponse(): LiveData<Resource<List<Category>>> = categoryLiveData
fun adResponse(): LiveData<Resource<List<Ad>>> = adLiveData
fun userResponse(): LiveData<Resource<List<User>>> = userLiveData
fun loadCategory() {
categoryLiveData.postValue(Resource.loading())
compositeDisposable.add(
homeRepository.getCategoryList()
.subscribe({ response ->
categoryLiveData.postValue(Resource.succeed(response))
}, { error ->
categoryLiveData.postValue(Resource.error(error))
})
)
}
fun loadAd() { // Same as above }
fun loadUser() { // Same as above }
}
HomeFragment.kt
fun init(){
// ..
viewmodel.loadCategory()
viewmodel.adResponse()
viewmodel.userResponse()
viewmodel.categoryResponse().observe(this, Observer {
when(it.status){
Status.SUCCEED -> { progressBar.toGone() }
Status.LOADING -> { progressBar.toVisible() }
Status.FAILED -> { progressBar.toGone() }
}
}
viewmodel.adResponse().observe(this, Observer { //Same as above }
viewmodel.userResponse().observe(this, Observer { //Same as above }
}
【问题讨论】:
标签: android kotlin rx-java rx-java2