调试Android应用时,在RxJava缓存线程中出现InterruptedException异常。

7

有时候在调试我的应用程序时,我会遇到RxCachedThreadScheduler-1中的InterruptedException。以下是跟踪信息:

Fatal Exception: java.lang.InterruptedException
       at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:1991)
       at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2025)
       at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1048)
       at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:776)
       at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1035)

我有一个自定义视图,在其中我可以这样订阅我的可观察对象:

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    sub = FollowHandler.getInstance().getObservable()
            .filter(new Func1<FollowEvent, Boolean>() {
                @Override
                public Boolean call(FollowEvent followEvent) {
                    if(followEvent == null || followEvent.user == null
                            || user == null)
                        return false;

                    return followEvent.user.id == user.id;
                }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<FollowEvent>() {
                @Override
                public void onCompleted() {}

                @Override
                public void onError(Throwable e) {}

                @Override
                public void onNext(FollowEvent followEvent) {
                    reactToThisNiceEvent(followEvent);
                }
            });
}

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();

    if(sub != null)
        sub.unsubscribe();
}

以下是可观测结果:

eventSubject.asObservable()
        .observeOn(Schedulers.io())
        .doOnNext(new Action1<FollowEvent>() {
            @Override
            public void call(FollowEvent followEvent) {
                if(followEvent != null)
                    doSomethingNice(followEvent);
            }
        })
        .share();

在这个事件中,eventSubject是一个简单的PublishSubject。 我正在使用RxAndroid 1.1.0和RxJava 1.1.0。

有人知道为什么会发生这种情况吗?

1个回答

0

我不确定为什么会发生这种情况,但尝试做这个:

sub = FollowHandler.getInstance().getObservable()
            .filter(...)
            .subscribeOn(Schedulers.io())    //  <<<<<<<<<<
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(...);

此外,我认为你不需要使用share()

eventSubject.asObservable()
        .doOnNext(...)
        .subscribeOn(Schedulers.io())   // <<<<< subscribeOn instead of observeOn, but actually, you don't need it here...
        .share();     // <<<<< remove it

我经常使用Subject作为事件总线,就像我上面描述的那样。我从来没有遇到过这样的问题。

P.S. 在onDetachedFromWindow()中最好检查订阅是否已取消。我知道这个方法在主线程中调用,并发访问此Subscription是不可能的,但我认为这是一个好习惯:

if(sub != null && !sub.isUnsubscribed())
        sub.unsubscribe();

谢谢你的答复。我会按照你的建议尝试使用subscribeOn和observeOn。不过,测试可能需要一些时间。 关于share,我确实需要它。因为在共享之前的任务必须在所有订阅者之间共享(并且所有订阅者的结果都相同)。如果我删除share,doOnNext将对所有订阅者调用(这是无意义的)。 感谢您对isUnsubscribed()检查的纠正。我完全忽略了它。 - mblcdr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接