我有一个用例,其中在Completable中初始化一些全局变量,然后在链的下一步中(使用andThen运算符)使用这些变量。

以下样本详细解释了我的用例

假设您有一个User

        class User {
            String name;
        }

我有一个这样的Observable,
        private User mUser; // this is a global variable

        public Observable<String> stringObservable() {
            return Completable.fromAction(() -> {
                mUser = new User();
                mUser.name = "Name";
            }).andThen(Observable.just(mUser.name));
        }

首先,我正在对Completable.fromAction进行一些初始化,我希望andThen运算符仅在完成Completable.fromAction之后才能启动。

这意味着我希望mUser运算符启动时可以将andThen初始化。

以下是我对这个可观察的订阅
             stringObservable()
            .subscribe(s -> Log.d(TAG, "success: " + s),
                    throwable -> Log.e(TAG, "error: " + throwable.getMessage()));

但是当我运行此代码时,出现错误
          Attempt to read from field 'java.lang.String User.name' on a null object reference

这意味着mUser为null,在执行andThen中的代码之前已启动Completable.fromAction。这里发生了什么事?

根据andThen的文档

最佳答案

问题不在于andThen,而在于Observable.just(mUser.name)中的语句andThenjust运算符将尝试立即创建可观察对象,尽管它仅在Completable.fromAction之后发出。

这里的问题是,当尝试使用just创建Observable时,mUser为null。

解决方案:您需要推迟String Observable的创建,直到发生订阅为止,直到andThen的上游开始发出。

代替andThen(Observable.just(mUser.name));
利用

 andThen(Observable.defer(() -> Observable.just(mUser.name)));

要么
 andThen(Observable.fromCallable(() -> mUser.name));

09-28 06:29