RxJava android - 观察者是否阻塞

RxJava android - does observer block

给定这个简单的观察者和订阅者组合,它简单地观察文件 IO,然后根据值在订阅者中更新:

Observable.just(preferences.getBoolean(C"vibrate", false))
            .subscribeOn(Schedulers.io())//observe on new thread
            .observeOn(AndroidSchedulers.mainThread()) //subscribe(listen) on main thread
            .subscribe(new Action1<Boolean>() {
                @Override
                public void call(Boolean shouldVibrate) {
                    if (shouldVibrate)
                        Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
                }

            });

我的问题是,观察者是否会阻塞直到写入完成?即使我指定了另一个线程(IO 线程),一旦被订阅者调用,这个观察者是否仍然阻塞?

你的 Observer 不会阻塞,因为你的操作在你订阅你的 Observer 之前完成(因此,它只会发出你的值)

关于您的代码(为简单起见,java 8 种样式):

Observable.just(preferences.getBoolean("vibrate", false))
        .subscribeOn(Schedulers.io())//observe on new thread
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(shouldVibrate) -> {
                if (shouldVibrate) {
                    Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
                }
        });

您可以将调用提取为变量 preferences.getBoolean(C"vibrate", false) :

Boolean vibrate = preferences.getBoolean("vibrate", false);
Observable.just(vibrate)
        .subscribeOn(Schedulers.io())//observe on new thread
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(shouldVibrate) -> {
                if (shouldVibrate) {
                    Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
                }
        });

如你所见,vibrate会先计算,然后主线程会被阻塞。

您应该使用 Observable.create 方法编写一个 "lazy" 调用您的方法

Observable.create(sub -> {
              Boolean vibrate = preferences.getBoolean("vibrate", false);
              sub.onNext(vibrate);
              sub.onCompleted();

         })
        .subscribeOn(Schedulers.io())//observe on new thread
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(shouldVibrate) -> {
                if (shouldVibrate) {
                    Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
                }
        });

使用此代码,仅当您订阅 Observer 时才会调用 Boolean vibrate = preferences.getBoolean("vibrate", false);

(关于您的 if,在您的订阅者中,您可以使用 filter 更改它)

        Observable.create(sub -> {
              Boolean vibrate = preferences.getBoolean("vibrate", false);
              sub.onNext(vibrate);
              sub.onCompleted();

         })
        .filter((value) -> value)
        .subscribeOn(Schedulers.io())//observe on new thread
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(shouldVibrate) -> {
                    Toast.makeText(context,"i should vibrate now",Toast.SHORT).show();
        });