Я довольно новичок в Rx Java, и я видел, что на этот вопрос несколько раз отвечали здесь, на SO, но ответы, которые даются, похоже, не работают для меня.
Итак, моя трассировка стека:
2018-12-04 10:51:03.072 17083-17227/com.doolin.gary.mybooks E/AndroidRuntime: FATAL EXCEPTION: RxCachedThreadScheduler-2
Process: com.test.test.mybooks, PID: 17083
io.reactivex.exceptions.OnErrorNotImplementedException: Only the original thread that created a view hierarchy can touch its views.
at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:77)
at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:67)
at io.reactivex.internal.operators.observable.ObservableHide$HideDisposable.onNext(ObservableHide.java:67)
at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.test(BehaviorSubject.java:570)
at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.emitNext(BehaviorSubject.java:565)
at io.reactivex.subjects.BehaviorSubject.onNext(BehaviorSubject.java:268)
at com.test.test.mybooks.viewmodel.BookSearchViewModel$getBookList$1.accept(BookSearchViewModel.kt:35)
at com.test.test.mybooks.viewmodel.BookSearchViewModel$getBookList$1.accept(BookSearchViewModel.kt:19)
at io.reactivex.internal.observers.DisposableLambdaObserver.onSubscribe(DisposableLambdaObserver.java:42)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onSubscribe(BodyObservable.java:46)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:37)
at io.reactivex.Observable.subscribe(Observable.java:12030)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:12030)
at io.reactivex.internal.operators.observable.ObservableDoOnLifecycle.subscribeActual(ObservableDoOnLifecycle.java:33)
at io.reactivex.Observable.subscribe(Observable.java:12030)
at io.reactivex.internal.operators.observable.ObservableObserveOn.subscribeActual(ObservableObserveOn.java:45)
at io.reactivex.Observable.subscribe(Observable.java:12030)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:579)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7753)
at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:3773)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:917)
at android.view.View.setFlags(View.java:14096)
at android.view.View.setVisibility(View.java:9992)
at com.test.test.mybooks.view.search.SearchFragment$observeScreenState$1.accept(SearchFragment.kt:91)
at com.test.test.mybooks.view.search.SearchFragment$observeScreenState$1.accept(SearchFragment.kt:28)
at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
2018-12-04 10:51:03.072 17083-17227/com.test.test.mybooks E/AndroidRuntime: ... 26 more
У меня есть список книг, которые я получаю с помощью модели представления:
class BookSearchViewModel @Inject constructor(private val app: Application,
private val bookRepository: BookRepository,
@Named(RxModule.IO_THREAD) private val ioThread: Scheduler,
@Named(RxModule.MAIN_THREAD) private val mainThread: Scheduler):
AndroidViewModel(app) {
private var disposables = CompositeDisposable()
private val screenState = BehaviorSubject.create<ScreenState>()
private val bookList = PublishSubject.create<List<BookSummary>>()
fun observeBookList(): Observable<List<BookSummary>> = bookList.hide()
fun observeScreenState(): Observable<ScreenState> = screenState.hide()
fun getBookList() {
disposables.add(bookRepository
.fetchBookList()
.doOnSubscribe { screenState.onNext(ScreenState.Loading("")) }
.observeOn(mainThread)
.subscribeOn(ioThread)
.subscribe(this::handleBookListSuccess, this::handleBookListError))
}
override fun onCleared() {
disposables.dispose()
super.onCleared()
}
private fun handleBookListSuccess(bookList: List<BookSummary>) {
screenState.onNext(ScreenState.Success)
this.bookList.onNext(bookList)
}
private fun handleBookListError(error: Throwable) {
screenState.onNext(ScreenState.Error(getErrorMessage(error)))
}
private fun getErrorMessage(error: Throwable): String {
return if (error.message.isNullOrEmpty()) {
app.getString(R.string.book_list_error)
} else {
error.message!!
}
}
}
Это прекрасно работает.Я наблюдаю в своем фрагменте следующее:
private fun addUIObservers() {
disposables.add(viewModel.observeBookList()
.subscribe {
bookAdapter.loadBooks(it)
})
}
private fun observeScreenState() {
disposables.add (viewModel
.observeScreenState()
.subscribe { screenState ->
when (screenState) {
is ScreenState.Success -> progress_layout.visibility = GONE
is ScreenState.Loading -> progress_layout.visibility = VISIBLE
is ScreenState.Error -> handleError(screenState)
}
})
}
Поэтому, когда пользователь нажимает на элемент книги, я затем открываю операцию с подробными сведениями о книге и, используя модель представления, извлекаю книгу, используя тот же шаблон, используя rx инаблюдение в упражнении.
Когда я возвращаюсь назад и возвращаюсь к предыдущему занятию / фрагменту, если я пытаюсь обновить, я получаю вышеуказанную ошибку.Это происходит только при возврате из операции детализации.Как я уже сказал, я очень плохо знаком с RX, поэтому, пожалуйста, будьте осторожны со мной, но если у кого-то есть какие-либо советы.Пожалуйста, не отмечайте это как уже отвеченный, поскольку эти ответы не работают для меня, и я наблюдаю и подписываюсь на правильные темы.