[英]RxJava2 with Room error handling - Database main thread exception
我正在嘗試從遠程源檢索項目,如果這不起作用(沒有互聯網),我想從會議室數據庫中檢索緩存的項目。 我為錯誤發生的時間創建了一個新的單曲,並指定了應該訂閱和觀察的線程。 我還是這個例外:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
這是檢索項目的方法:
public LiveData<List<Article>> getNewsArticles() {
return LiveDataReactiveStreams.fromPublisher(
newsService.getNewsArticles()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.onErrorResumeNext(throwable ->
Single.just(newsDao.findAllForNumber(AMOUNT_OF_ARTICLES_PER_PAGE))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess(newsArticles -> Completable.fromAction(() ->
newsDao.insertAll(newsArticles))
.subscribeOn(Schedulers.io()))
.toFlowable());
}
LiveDataReactiveStreams其轉換成livedata對象和處理訂閱新資料,所以我的觀點只知道livedata。
我只是似乎無法使onErrorResumeNext調用在后台線程上工作。
任何幫助將不勝感激!
回答
我最終用以下代碼解決了這個問題:
public LiveData<List<Article>> getNewsArticles() {
return LiveDataReactiveStreams.fromPublisher(
newsService.getNewsArticles()
.observeOn(Schedulers.io())
.doOnSuccess(newsArticles -> newsDao.insertAll(newsArticles))
.onErrorResumeNext(throwable -> Single.fromCallable(() -> newsDao.findAllForNumber(AMOUNT_OF_ARTICLES_PER_PAGE)))
.toFlowable());
}
在RxJava方法subscribeOn指定在其上可觀察到的將操作的調度器。 但是方法observeOn指定了調度程序,觀察者將在該調度程序上觀察此Observable。
簡單來說:
Single
.zip(observable1.getList(), observable2.getAnotherList()) // Simple zip for example
.observeOn(AndroidSchedulers.mainThread()) // switch to main thread
.map(mapper.map(list1, list2)) // this command will execute on main thread
.observeOn(Schedulers.io()) // switch to io thread
.map(anotherMapper.map(complexList)) // this command will execute on io thread
.observeOn(AndroidSchedulers.mainThread()) // switch to main thread
.subscribeOn(Schedulers.io()) // specify thread for zip command
ObserveOn僅在下游起作用。 beforeOn之后的所有方法均已移至IO線程。 而watchOn之前的方法仍在主線程中。
在您的示例中,您嘗試在主線程上調用room dao命令,並且系統不允許在主線程上執行。 您可以在每個命令上設置斷點,然后在IDE中准確查找要執行命令的線程名稱。
有關更復雜的示例,請參見本文 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.