CalledFromWrongThreadException даже при использовании AndroidSchedulers.mainThread()
Хорошо, мы реализовали слой MVP для, ну презентации и использовать RxJava и RxAndroid с ним. Мы взяли Этот пример и построили на нем.
Когда ведущий вызывается, чтобы начать действовать, он передаетSubscriber
взаимодействующему с моделью. Взаимодействующий создает Observable
и устанавливает observeOn(Schedulers.io())
и subscribeOn(AndroidSchedulers.mainThread())
. Таким образом (мы думали), когда вызов возвращается к Subscriber
(в Презентаторе), каждый вызов будет находиться в потоке пользовательского интерфейса. В пределах Subscriber
мы связываем данные с представлением. Однако, это вызывает a CalledFromWrongThreadException
:
07-28 09:12:48.844 17424 17566 AndroidRuntime E FATAL EXCEPTION: RxCachedThreadScheduler-1
07-28 09:12:48.844 17424 17566 AndroidRuntime E Process: [PACKAGE NAME], PID: 17424
07-28 09:12:48.844 17424 17566 AndroidRuntime E java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.lang.Thread.run(Thread.java:818)
07-28 09:12:48.844 17424 17566 AndroidRuntime E Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:137)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.OperatorSubscribeOn$1$1$1.onNext(OperatorSubscribeOn.java:76)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.NotificationLite.accept(NotificationLite.java:150)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:205)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:159)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
07-28 09:12:48.844 17424 17566 AndroidRuntime E ... 7 more
07-28 09:12:48.844 17424 17566 AndroidRuntime E Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.
07-28 09:12:48.844 17424 17566 AndroidRuntime E ... 15 more
07-28 09:12:48.844 17424 17566 AndroidRuntime E Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received =>
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.util.Log.getStackTraceString(Log.java:499)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.android.internal.os.RuntimeInit.Clog_e(RuntimeInit.java:59)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.android.internal.os.RuntimeInit.access$200(RuntimeInit.java:43)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:91)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:66)
07-28 09:12:48.844 17424 17566 AndroidRuntime E ... 7 more
07-28 09:12:48.844 17424 17566 AndroidRuntime E Caused by: java.lang.IllegalStateException: Method call should happen from the main thread.
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.squareup.picasso.Utils.checkMain(Utils.java:136)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.squareup.picasso.RequestCreator.into(RequestCreator.java:615)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.nextmarkets.next.education.view.TradingIdeaHistoryFragment.setCoachAvatar(TradingIdeaHistoryFragment.java:94)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.nextmarkets.next.education.TradingIdeaHistoryPresenter$TradingIdeaHistorySubscriber.onNext(TradingIdeaHistoryPresenter.java:55)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at com.nextmarkets.next.education.TradingIdeaHistoryPresenter$TradingIdeaHistorySubscriber.onNext(TradingIdeaHistoryPresenter.java:38)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:130)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.OperatorSubscribeOn$1$1$1.onNext(OperatorSubscribeOn.java:76)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.NotificationLite.accept(NotificationLite.java:150)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:205)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:159)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
07-28 09:12:48.844 17424 17566 AndroidRuntime E ... 7 more
07-28 09:12:48.844 17424 17566 AndroidRuntime E Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7062)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.view.ViewRootImpl.requestChildFocus(ViewRootImpl.java:3098)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.view.ViewGroup.requestChildFocus(ViewGroup.java:678)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.view.ViewGroup.requestChildFocus(ViewGroup.java:678)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.view.ViewGroup.requestChildFocus(ViewGroup.java:678)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at android.view.ViewGroup.requestChildFocus(ViewGroup.java:678)
07-28 09:12:48.844 17424 17566 AndroidRuntime E at andro
В этом месте stacktrace фактически обрывается.
Конечно, мы могли бы просто запустить его в потоке пользовательского интерфейса вручную в представлении, но это не должно быть необходимо, когда мы устанавливаем subscribeOn(AndroidSchedulers.mainThread())
, не так ли? Мы уже делали это раньше без проблем. Мы что-то упустили?
Еще некоторые детали реализации:
Мы используем Dagger2 для DI и Interactor создается в Module
и получает планировщики через конструктор.
@Provides
MyInteractor provideMyInteractor() {
return new MyInteractorImpl(Schedulers.io(), AndroidSchedulers.mainThread());
}
Ведущий получает взаимодействующий через инъекцию конструктора и презентатор вводится в представление через Component
.
1 ответ:
Не уверен, что вы там делаете, но просто чтобы напомнить и уточнить:
метод subscribeOn задает поток, на котором будет выполняться метод onSubscribe .
observeOn метод задает поток, на котором onNext/онеррор/onCompleted будет выполнен.
Вы говорите - " Interactor создает наблюдаемое и устанавливает observeOn(Schedulers.io ()) и subscribeOn (AndroidSchedulers.mainThread ()).- Вы, наверное, перепутали. эти два метода.