![](/img/trans.png)
[英]Android Retrofit2/RxJava2/Room - Simple Data Processing
[英]Loading data from Database + Network (Room + Retrofit + RxJava2)
我有一個示例API請求,它返回用戶監視列表的列表。 我想在用戶加載監視列表屏幕時實現以下流程 :
立即從DB緩存加載數據。( cacheWatchList
)
在后台啟動RetroFit網絡呼叫。
一世。 onSuccess
返回apiWatchList
II。 onError
返回cacheWatchList
Diff cacheWatchList
vs apiWatchList
一世。 相同 - >一切都很好,因為數據已經顯示給用戶什么都不做。
II。 不同 - >將apiWatchList
保存到本地存儲並將apiWatchList
發送到下游。
到目前為止我做了什么?
Watchlist.kt
data class Watchlist(
val items: List<Repository> = emptyList()
)
LocalStore.kt (Android室)
fun saveUserWatchlist(repositories: List<Repository>): Completable {
return Completable.fromCallable {
watchlistDao.saveAllUserWatchlist(*repositories.toTypedArray())
}
}
RemoteStore.kt (改造api調用)
fun getWatchlist(userId: UUID): Single<Watchlist?> {
return api.getWatchlist(userId)
}
DataManager.kt
fun getWatchlist(userId: UUID): Flowable<List<Repository>?> {
val localSource: Single<List<Repository>?> =
localStore.getUserWatchlist()
.subscribeOn(scheduler.computation)
val remoteSource: Single<List<Repository>> = remoteStore.getWatchlist(userId)
.map(Watchlist::items)
.doOnSuccess { items: List<Repository> ->
localStore.saveUserWatchlist(items)
.subscribeOn(scheduler.io)
.subscribe()
}
.onErrorResumeNext { throwable ->
if (throwable is IOException) {
return@onErrorResumeNext localStore.getUserWatchlist()
}
return@onErrorResumeNext Single.error(throwable)
}
.subscribeOn(scheduler.io)
return Single.concat(localSource, remoteSource)
}
上述流程的問題在於,即使兩個數據都相同,它onNext
為每個流源調用onNext
兩次到下游(演示者)。
我可以在演示者中執行數據差異邏輯並相應地更新,但我希望DataManager
類為我處理邏輯(CleanArchitecture,SOC)。
我的問題?
實現上述邏輯的最佳方法是什么?
我是否泄漏了DataManager中的內部訂閱(參見: doOnSuccess
代碼)? 當演示者被銷毀時,我正在處理外部訂閱。
fun getWatchlist(userId: UUID): Observable<List<Repository>?> {
val remoteSource: Single<List<Repository>> =
remoteStore.getWatchlist(userId)
.map(Watchlist::items)
.subscribeOn(scheduler.io)
return localStore.getUserWatchlist()
.flatMapObservable { listFromLocal: List<Repository> ->
remoteSource
.observeOn(scheduler.computation)
.toObservable()
.filter { apiWatchList: List<Repository> ->
apiWatchList != listFromLocal
}
.flatMapSingle { apiWatchList ->
localSource.saveUserWatchlist(apiWatchList)
.andThen(Single.just(apiWatchList))
}
.startWith(listFromLocal)
}
}
逐步說明:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.