订阅后,一次性对象为null

时间:2018-12-22 14:26:22

标签: android java-8 reactive-programming rx-java2

在下面的代码中,我创建了一个示例,以学习使用Rx进行函数式编程。我正在尝试将HandlerThread处理为可观察的。在onResume()中,我订阅了Single.just,以启动 HandlerThread

对于SingleObserver回调,尽管收到onSuccess()中的值,但Disposable中的onSubscribe()对象始终为null

我还发布了日志。请查看一下,并告诉我Disposable对象d为何是null的原因。

代码

onResume() {
    this.mMyHandlerThreadInitSingleObs = Single.just(this.getInitializedHandlerThread())
            .map(myHandlerThread->{
                Log.d(TAG_LOG, "BEFORE .start()");
                myHandlerThread.start();
                Log.d(TAG_LOG, "AFTER .start()");

                return this.mMyHandlerThread;
            });
    this.mMyHandlerThreadInitSingleObs
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this.getSingleObserver());
}

private SingleObserver<HandlerThread> getSingleObserver() {
    String TAG_LOG = ActMain.TAG_LOG + "." + "getSingleObserver()";
    return new SingleObserver<HandlerThread>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.v(TAG_LOG, "[onSubscribe] d: " + d);
        }

        @Override
        public void onSuccess(HandlerThread is) {
            Log.v(TAG_LOG, "[onSuccess] is: " + is);
        }

        @Override
        public void onError(Throwable e) {
            Log.e(TAG_LOG, "[onError]");
        }
    };
}

logcat

2018-12-22 14:56:50.329 12611-12611 V/ActMain: onStart
2018-12-22 14:56:50.332 12611-12611 V/ActMain.MyHandlerThread: constructor called
2018-12-22 14:56:50.333 12611-12611 V/ActMain.getSingleObserver(): [onSubscribe] d: null//<--------------------
2018-12-22 14:56:50.349 12611-12611 D/ActMain.onResume(): BEFORE .start()
2018-12-22 14:56:50.349 12611-12611 D/ActMain.onResume(): AFTER .start()
2018-12-22 14:56:50.350 12611-12630 V/ActMain.MyHandlerThread.onLooperPrepared: ..
2018-12-22 14:56:50.350 12611-12630 D/ActMain.MyHandlerThread.onLooperPrepared: this.getLooper(): Looper (my HandlerThread, tid 416) {2f35ee2}
2018-12-22 14:56:50.363 12611-12630 I/ActMain.MyHandlerThread.onLooperPrepared: [onSubscribe] d: null
2018-12-22 14:56:50.377 12611-12633 D/ActMain.MyHandlerThread.onLooperPrepared.emitter.onComplete():: this.getLooper() initialized: Looper (my HandlerThread, tid 416) {2f35ee2}
2018-12-22 14:56:50.377 12611-12633 I/ActMain.MyHandlerThread.onLooperPrepared: [onComplete]
2018-12-22 14:56:50.425 12611-12611 V/ActMain.getSingleObserver(): [onSuccess] is: Thread[my HandlerThread,5,main]
2018-12-22 14:56:50.514 1700-1724 I/ActivityManager: Displayed com.example.amrbakri.rxhandlerthread_01/.ActMain: +340ms

1 个答案:

答案 0 :(得分:1)

事实证明,这是一个有趣的问题。来自RxJava2(Single)的文档

  

“单”的行为与“可观察”相似,但只能发出   一个成功值或一个错误(没有“ onComplete”   通知,因为有一个可观察对象。

     

Single类实现SingleSource基本接口,并且   它与之交互的默认消费者类型是通过   subscription(SingleObserver)方法。

似乎您使用的是SingleObserver而不是DisposableSingleObserver

文档提到:

  

请注意,根据设计,通过订阅(SingleObserver)进行的订阅不能   从外部放置(因此,   subscription(SingleObserver)方法,这是   SingleObserver的实现者以允许发生这种情况。 RxJava的   通过标准DisposableSingleObserver支持此类用法   实例。为了方便起见,subscribeWith(SingleObserver)方法是   还提供以允许使用SingleObserver(或子类)   流利地应用实例(例如在示例中)   以上)。

因此,请尝试这样做:

Disposable d = Single.just("Hello World")
    .delay(10, TimeUnit.SECONDS, Schedulers.io())
    .subscribeWith(new DisposableSingleObserver<String>() {
        @Override
        public void onStart() {
            System.out.println("Started");
        }

        @Override
        public void onSuccess(String value) {
            System.out.println("Success: " + value);
        }

        @Override
        public void onError(Throwable error) {
            error.printStackTrace();
        }
    });