RxJava -Do订阅者只运行一次

时间:2015-01-20 01:33:41

标签: android observer-pattern rx-java

我对订阅者以及他们对观察者做出反应时有些困惑。假设我有一个简单的观察者与一个执行动作的订阅者:

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();
                }
            });

我意识到当第一次看到这段代码时,观察者会马上被调用。但是,如果之后再次更改共享首选项,此代码会自动再次运行,还是仅在每次调用subscribe时运行?如果我希望每次共享偏好被改变时运行(有点像观察者),该怎么办?

1 个答案:

答案 0 :(得分:2)

这实际上取决于观察力。我建议在反应性Observable文档上阅读"Hot" and "Cold" Observables

在你的情况下,这是一个冷可观察。它将在每次订阅时重新订阅。但是,您只订阅一次。您的代码段实际上会阻止首选项获取(可能不是一个大问题),但它只会发出一个首选项。

我建议在RxAndroid扩展库中使用已经使用的RxJava ContentObservable类(因为AndroidSchedulers)。

它看起来像这样(这是餐巾纸后面的代码,我没有编译或运行它):

// Defer the observable so it gets a fresh preference value. Also, we'll
// be using it a few times.
final Observable<Boolean> vibratePreference = Observable.defer(
    new Func0<Observable<Boolean>>() {

      @Override
      public Observable<Boolean> call() {
        return Observable.just(preferences.getBoolean("vibrate", false));
      }

    });

vibratePreference
    .concatWith(ContentObservable.fromSharedPreferencesChanges(preferences)
        // Only consider changes to the vibrate preference.
        .filter(new Func1<String, Boolean>() {

          @Override
          public Boolean call(final String key) {
            return "vibrate".equals(key);
          }

        })
        // Each time the preference changes, get the latest value.
        .flatMap(new Func1<String, Observable<Boolean>>() {

          @Override
          public Observable<Boolean>(final String unusedKey) {
            return vibratePreference;
          }

        }))
    .scheduleOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe( /* ...and so on. */ );

此外,如果您是在活动或片段上执行此操作,我强烈建议您在RxAndroid的bindActivity中查看bindFragmentAppObservable,以确保绑定此可观察对象到了生命周期。您还可以在CompositeSubscription中存储可以清空的onPause,并在onResume中恢复订阅。这些稍微偏离主题,但很可能很快就会有用。