RxJava1升級到RxJava2的一些差異記錄

說明

mMessageHelper.appendLine("Observable emit 3");

理解成如下打Log,詳見 https://github.com/tik5213/DUnit

Log.e("TAG","Observable emit 3");

rxjava2-編譯器提示“The result of subscribe is not used”

如下書寫,編譯器提示 “The result of subscribe is not used”

            Observable.create(new ObservableOnSubscribe<Integer>() {  // 第一步:初始化Observable
                @Override
                public void subscribe(ObservableEmitter<Integer> emitter) {
                    mMessageHelper.printLine("Observable emit 1");
                    emitter.onNext(1);
                    mMessageHelper.appendLine("Observable emit 2");
                    emitter.onNext(2);
                    mMessageHelper.appendLine("Observable emit 3");
                    emitter.onNext(3);
                    mMessageHelper.appendLine("Observable emit 4");
                    emitter.onNext(4);
                }
            })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    mMessageHelper.printLine("accept " + integer);
                }
            });

原因

沒有對 subscribe 的返回的對象進行生命週期管理,可能產生內存泄露 

解決方案

  1. 創建一個 CompositeDisposable 對象
  2. 將 subscribe 的返回值添加到上面創建的對象中
  3. 在適當的時候調 用CompositeDisposable 對象的 dispose() 方法(比如,在Activity將要銷燬的時候)

改正後的代碼 

        CompositeDisposable compositeDisposable = new CompositeDisposable();
        @Override
        public void callUnit() {
            Disposable disposable = Observable.create(new ObservableOnSubscribe<Integer>() {  // 第一步:初始化Observable
                @Override
                public void subscribe(ObservableEmitter<Integer> emitter) {
                    mMessageHelper.printLine("Observable emit 1");
                    emitter.onNext(1);
                    mMessageHelper.appendLine("Observable emit 2");
                    emitter.onNext(2);
                    mMessageHelper.appendLine("Observable emit 3");
                    emitter.onNext(3);
                    mMessageHelper.appendLine("Observable emit 4");
                    emitter.onNext(4);
                }
            })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    mMessageHelper.appendLine("accept " + integer);
                }
            });
            compositeDisposable.add(disposable);
            //在 Activity 的 onDestroy 的裏面調
            //compositeDisposable.dispose();
        }

根本原因

rx 團隊在 subscribe 方法上添加了 @CheckReturnValue 註解,當 FindBugs 檢查到一個函數調用返回值被丟棄時會給出警告。

使用FindBugs檢查你的返回值

示例: 

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public int test(){
    return 1 + 2;
}

參考網址

The result of subscribe is not used

onCompleted、onNext、onError 三者的關係

onCompleted():事件隊列完結。RxJava 僅把每個事件單獨處理,還會把它們看做一個隊列。RxJava 規定,當不會再有新的 onNext() 發出時,需要觸發 onCompleted() 方法作爲標誌。

onError():事件隊列異常。在事件處理過程中出異常時,onError() 會被觸發,同時隊列自動終止,不允許再有事件發出。

在一個正確運行的事件序列中,onCompleted() 和 onError() 有且只有一個,並且是事件序列中的最後一個。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在隊列中調用了其中一個,就不應該再調用另一個。

RxJava1 Action1 與 Func1的區別

Func1與Action1非常相似,也是RxJava的一個接口,用於包裝含有一個參數的方法。Func1 和 Action1 的區別在於,Func1 包裝的是有返回值的方法。 

RxJava1 在 map 變換時 return null 會繼續執行,RxJava2 則直接報錯

RxJava1 會繼續執行

/**
     * subscribeOn 放在第一位
     * subscribeOn 只有第一次出現時纔有效,並且,無論 subscribeOn 在哪個位置,永遠控制 Observable 所在的執行線程。
     */
    @DUnit(group = RxJava2Or1SchedulersGroup.class ,name = "RxJava1Schedulers_subscribeOn_fist - rx1 return null會繼續執行")
    public static class RxJava1Schedulers_subscribeOn_fist extends AbstractDisplayUnit {
        @Override
        public void callUnit() {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    Observable.unsafeCreate(new Observable.OnSubscribe<Integer>() {
                        @Override
                        public void call(Subscriber<? super Integer> subscriber) {
                            mMessageHelper.printLine("onNext 1 io - thread:" + Thread.currentThread().getName());
                            subscriber.onNext(1);
                        }
                    })
                            .subscribeOn(rx.schedulers.Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .map(new Func1<Integer, String>() {
                                @Override
                                public String call(Integer integer) {
                                    mMessageHelper.appendLine("main - thread:" + Thread.currentThread().getName());
                                    return null;
                                }
                            })
                            .observeOn(rx.schedulers.Schedulers.newThread())
                            .map(new Func1<String, Boolean>() {
                                @Override
                                public Boolean call(String s) {
                                    mMessageHelper.appendLine("new - thread:" + Thread.currentThread().getName());
                                    return null;
                                }
                            })
                            .observeOn(rx.schedulers.Schedulers.io())
                            .map(new Func1<Boolean, String>() {
                                @Override
                                public String call(Boolean aBoolean) {
                                    mMessageHelper.appendLine("io - thread:" + Thread.currentThread().getName());
                                    return null;
                                }
                            })
                            .observeOn(AndroidSchedulers.mainThread())
                            .map(new Func1<String, Integer>() {
                                @Override
                                public Integer call(String s) {
                                    mMessageHelper.appendLine("main - thread:" + Thread.currentThread().getName());
                                    return null;
                                }
                            })
                            .observeOn(rx.schedulers.Schedulers.io())
                            .subscribe(new Subscriber<Integer>() {
                                @Override
                                public void onCompleted() {

                                }

                                @Override
                                public void onError(Throwable e) {

                                }

                                @Override
                                public void onNext(Integer integer) {
                                    mMessageHelper.appendLine("io - thread:" + Thread.currentThread().getName());
                                }
                            });
                }
            }, "testThread001")
                    .start();


        }
    }

結果:

msg: onNext 1 io - thread:RxIoScheduler-7
msg: main - thread:main
msg: new - thread:RxNewThreadScheduler-2
msg: io - thread:RxIoScheduler-6
msg: main - thread:main
msg: io - thread:RxIoScheduler-5

RxJava2 map 返回 null 會報錯進入 error 中(或者閃退)

    /**
     * https://maxwell-nc.github.io/android/rxjava2-1.html
     *
     * http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0907/6604.html
     * 首先,創建Observable時,回調的是ObservableEmitter,字面意思即發射器,用於發射數據(onNext)和通知(onError/onComplete)。
     * 其次,創建的Observer中多了一個回調方法onSubscribe,傳遞參數爲Disposable ,Disposable相當於RxJava1.x中的Subscription,用於解除訂閱。
     * 你可能納悶爲什麼不像RxJava1.x中訂閱時返回Disposable,而是選擇回調出來呢。官方說是爲了設計成Reactive-Streams架構。
     * 不過仔細想想這麼一個場景還是很有用的,假設Observer需要在接收到異常數據項時解除訂閱,
     * 在RxJava2.x中則非常簡便,如下操作即可。
     */
    @DUnit(group = RxJava2Or1SchedulersGroup.class ,name = "RxJava2Schedulers_Single_Consumer - rx2 return null不會繼續執行")
    public static class RxJava2Schedulers_Single_Consumer extends AbstractDisplayUnit {

        @Override
        public void callUnit() {
            Disposable disposable = Single.create(new SingleOnSubscribe<Integer>() {
                @Override
                public void subscribe(SingleEmitter<Integer> emitter) throws Exception {
                    mMessageHelper.appendLine("emitter new - thread:" + Thread.currentThread().getName());
                    emitter.onSuccess(123);
                }
            })
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread())
                    .map(new Function<Integer, String>() {
                        @Override
                        public String apply(Integer integer) throws Exception {
                            mMessageHelper.appendLine("main - thread:" + Thread.currentThread().getName());
                            return null;
                        }
                    })
                    .observeOn(Schedulers.newThread())
                    .map(new Function<String, Boolean>() {
                        @Override
                        public Boolean apply(String s) throws Exception {
                            mMessageHelper.appendLine("new - thread:" + Thread.currentThread().getName());
                            return null;
                        }
                    })
                    .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread())
                    .map(new Function<Boolean, Integer>() {
                        @Override
                        public Integer apply(Boolean aBoolean) throws Exception {
                            mMessageHelper.appendLine("main - thread:" + Thread.currentThread().getName());
                            return null;
                        }
                    })
                    .observeOn(io.reactivex.schedulers.Schedulers.single())
                    .toObservable()
                    .subscribe(new Consumer<Integer>() {
                        @Override
                        public void accept(Integer integer) throws Exception {
                            mMessageHelper.appendLine("accept success single - thread:" + Thread.currentThread().getName());
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            mMessageHelper.appendLine("accept error single - thread:" + Thread.currentThread().getName());
                        }
                    });

            if(SystemClock.currentThreadTimeMillis() % 2 == 0){
//                disposable.dispose();
            }

        }
    }

結果:

msg: emitter new - thread:RxNewThreadScheduler-1
msg: main - thread:main
msg: accept error single - thread:RxSingleScheduler-1

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章