RxJava 2导致抛出CalledFromWrongThreadException

时间:2017-03-05 20:30:29

标签: android mvp rx-java2

目前正试图用延迟来模拟与RxJava 2(2.0.6)的api调用。 它在我的视图层(Activity)中抛出CalledFromWrongThreadException。

这是我的演示者中的Observable

   view.refreshLoadStart();
   Observable.just(createTicketArray(10))
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .delay(5, TimeUnit.SECONDS)
            .subscribe(new Observer<ArrayList<Ticket>>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(ArrayList<Ticket> tickets) {
                    if (getView() != null){
                        view.showTickets(tickets);
                    }
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                    if (getView() != null){
                        view.refreshLoadComplete();
                    }
                }

                @Override
                public void onComplete() {
                    if (getView() != null){
                        view.refreshLoadComplete();
                    }
                }
            });

以下是我的活动中的查看方法

    @Override
public void showTickets(final ArrayList<Ticket> tickets) {


//        runOnUiThread(new Runnable() {
//            @Override
//            public void run() {
    if (recyclerView.getAdapter() == null){
        adapter = new TicketAdapter(tickets);
        recyclerView.setAdapter(adapter);
    } else {
        adapter.setTickets(tickets);
        adapter.notifyDataSetChanged();
    }
    recyclerView.setHasFixedSize(true);
//            }
//        });

}

@Override
public void refreshLoadComplete() {
//        runOnUiThread(new Runnable() {
//            @Override
//            public void run() {
    swipeRefreshLayout.setRefreshing(false);
    Toast.makeText(TicketActivity.this, "Completed", Toast.LENGTH_SHORT).show();
//            }
//        });
}

@Override
public void refreshLoadStart() {
//        runOnUiThread(new Runnable() {
//            @Override
//            public void run() {
    swipeRefreshLayout.setRefreshing(true);
//            }
//        });
}

以下是异常的堆栈跟踪:

Process: com.timmccarthy.litt, PID: 22060
                                                                  io.reactivex.exceptions.UndeliverableException: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                      at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:366)
                                                                      at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:62)
                                                                      at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)
                                                                      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154)
                                                                      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
                                                                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                      at java.lang.Thread.run(Thread.java:818)
                                                                   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:8128)
                                                                      at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1220)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.view.View.requestLayout(View.java:20085)
                                                                      at android.support.v7.widget.RecyclerView.requestLayout(RecyclerView.java:3576)
                                                                      at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:4620)
                                                                      at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:10448)
                                                                      at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:6105)
                                                                      at com.timmccarthy.litt.ui.ticket.TicketActivity.showTickets(TicketActivity.java:82)
                                                                      at com.timmccarthy.litt.ui.ticket.TicketPresenter$1.onNext(TicketPresenter.java:46)
                                                                      at com.timmccarthy.litt.ui.ticket.TicketPresenter$1.onNext(TicketPresenter.java:37)
                                                                      at io.reactivex.observers.SerializedObserver.onNext(SerializedObserver.java:111)
                                                                      at io.reactivex.internal.operators.observable.ObservableDelay$DelayObserver$1.run(ObservableDelay.java:84)
                                                                      at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)
                                                                      at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51) 
                                                                      at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                                                                      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:154) 
                                                                      at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269) 
                                                                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                                                                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                                                                      at java.lang.Thread.run(Thread.java:818) 

基本上我问为什么抛出这个异常,因为我在观察主要线程而不是另一个线程的Observable上?

p.s我确实找到了一个修复程序,这是我的代码中已注释掉的部分,我只是将其视为一个快速解决方案而且它并没有真正解决为什么我会得到异常。

2 个答案:

答案 0 :(得分:0)

实际上,实际上,您正在修改不在主线程中的视图。试试这个subscribeOn(Schedulers.newThread())

这一行会被执行吗? Toast.makeText(TicketActivity.this, "Completed", Toast.LENGTH_SHORT).show();注释掉的部分不会起作用,因为你已经在主线程上了。

答案 1 :(得分:0)

弄清楚我哪里出错了。

我的'swipetorefresh'监听器在我的演示者上调用了一个刷新方法,该方法有一个单独的可观察对象。

删除了第二个可观测量,所有问题都消失了。