說明
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 的返回的對象進行生命週期管理,可能產生內存泄露
解決方案
- 創建一個 CompositeDisposable 對象
- 將 subscribe 的返回值添加到上面創建的對象中
- 在適當的時候調 用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 檢查到一個函數調用返回值被丟棄時會給出警告。
示例:
@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