如何管理RxJava中所需的Looper线程

时间:2016-09-12 11:26:46

标签: android rx-java rx-android

我希望将Observable封装在一个查询ContentProvider的逻辑中,并订阅ContentProvider光标以提供持续更新。

由于observable做IO工作,我需要在Schedulers.io()订阅它。问题是我不能注册ContentObserver,因为它需要一个looper准备好的线程。

在单个Observable中管理该内容并封装的建议方法是什么。

代码说明:

public Observable<Integer> unreadCountObservable() {
    return Observable.create(subscriber -> {
        new UnreadCountObservable(subscriber);
    });
}

private class UnreadCountObservable {
    private Subscriber subscriber;

    public UnreadCountObservable(Subscriber subscriber) {
        this.subscriber = subscriber;
        Cursor cursor = queryUnread(subscriber);
        cursor.registerContentObserver(observer);
        subscriber.add(Subscriptions.create(() -> {
            cursor.unregisterContentObserver(observer);
            cursor.close();
        }));
    }

    @NonNull
    private Cursor queryUnread(Subscriber subscriber) {
        Cursor cursor = contextProvider.getContext().getContentResolver().query(Uri.parse(CONTENT_URI),SMS_PROJECTION,SMS_SELECTION_UNREAD,SMS_PROJECTION,null);
        if(cursor.moveToNext()) {
            Integer count = cursor.getInt(0);
            subscriber.onNext(count);
        } else {
            subscriber.onNext(0);
        }
        return cursor;
    }

    private ContentObserver observer = new ContentObserver(new Handler()) {
        @Override
        public boolean deliverSelfNotifications() {
            return false;
        }

        @Override
        public void onChange(boolean selfChange) {
            Timber.d("New sms data changed");
            queryUnread(subscriber);
        }
    };
}

注1 上述代码的问题在于,由于registerObserver无法使用.subscribeOn(Schedulers.io()调用,如果将其称为mainThread,则查询也会在其上运行)

注意:将所有内容封装在一个Observable中是关键要求和此问题的动机

我现在最好的想法是为我使用Observable的活动创建一个HandlerThread并使用该线程中的looper。但是想知道是否有更好的替代方案,并且如果制作一个通用调度程序(例如looperIoScheduler())有意义就会导致问题。

2 个答案:

答案 0 :(得分:1)

Observable链中,您可以根据需要随时更改帖子。看看here

函数rx.Observable#observeOn(rx.Scheduler)可以位于链中的任何位置。尝试做这样的事情(伪代码):

Observable.just(cursor)
        .observeOn(AndroidSchedulers.mainThread())
        .map((Cursor) -> {
                cursor.registerContentObserver(observer);
                return cursor;
            }
        }).observeOn(Schedulers.io());
subscriber.add(Subscriptions.create(() -> {
        cursor.unregisterContentObserver(observer);
        cursor.close();
    }));

答案 1 :(得分:-1)

好的,为什么要赢得这项工作呢?

public Observable<Integer> unreadCountObservable() {
    return Observable.defer(() -> Observable.create(subscriber -> {
        new UnreadCountObservable(subscriber);
    }))
    .subscribeOn(Schedulers.io());
}