本篇記錄公司項(xiàng)目用的RxJava遇到的問(wèn)題烙如,本篇持續(xù)更新!
極力推薦 RxJava 入門(mén)到精通文章https://github.com/THEONE10211024/RxJavaSamples
歡迎加群討論(158943444):
RxJava RxAndroid Retrofit RxBus Dragger2 OkHttp MVP MVVM DataBinding
1、防止內(nèi)存泄漏CompositeSubscription
使用CompositeSubscription可以防止RxJava帶來(lái)的內(nèi)存泄漏,因?yàn)橛肦x流的地方比較多,所以直接把CompositeSubscription放到BasePresenter中绳慎,方便快捷
public class BasePresenter<T extends BaseView> implements Presenter<T>{
public CompositeSubscription mCompositeSubscription;
public T view;
@Override
public void attachView(T t) {
mCompositeSubscription = new CompositeSubscription();
view = t;
}
@Override
public void detachView() {
mCompositeSubscription.unsubscribe();
mCompositeSubscription = null;
view = null;
}
public T getView(){
return view;
}
}
然后在每一個(gè)Presenter中,只要把用到的RxJava流加到CompositeSubscription里面就可以了 mCompositeSubscription.add(RxJava流)兔朦,這樣不用擔(dān)心RxJava帶來(lái)的內(nèi)存泄漏了偷线。
2、線程切換compose的使用
使用RxJava的都知道沽甥,線程切換時(shí)多么的優(yōu)雅声邦!
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
但是每次都要這樣寫(xiě)也是挺煩的,用compose可以更優(yōu)雅的切換線程.
在Rx流的最后用 compose(RxUtils.applyIOToMainThreadSchedulers())
這一句代碼就可以切換了摆舟!
public class RxUtils {
private staticObservable.TransformerioToMainThreadSchedulerTransformer;
private static Observable.Transformer newThreadToMainThreadSchedulerTransformer;
static {
ioToMainThreadSchedulerTransformer = createIOToMainThreadScheduler();
newThreadToMainThreadSchedulerTransformer = createNewThreadToMainThreadScheduler();
}
private static <T> Observable.Transformer<T, T> createIOToMainThreadScheduler() {
return tObservable -> tObservable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread());
}
public static <T> Observable.Transformer<T, T> applyIOToMainThreadSchedulers() {
return ioToMainThreadSchedulerTransformer;
}
private static <T> Observable.Transformer<T, T> createNewThreadToMainThreadScheduler(){
return tObservable -> tObservable.subscribeOn(Schedulers.newThread())
.unsubscribeOn(Schedulers.computation())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
public static <T> Observable.Transformer<T, T> applyNewThreadToMainThreadSchedulers(){
return newThreadToMainThreadSchedulerTransformer;
}
}
3亥曹、onErrorResumeNext的使用
情景:
當(dāng)我們請(qǐng)求數(shù)據(jù)的時(shí)候,先請(qǐng)求網(wǎng)絡(luò)上面的數(shù)據(jù)恨诱,沒(méi)有的話請(qǐng)求硬盤(pán)上面的數(shù)據(jù)媳瞪,并且想在同一個(gè)Rx流中處理這些操作.
方法:
使用onErrorResumeNext操作符,可以很好的完成上面的需求照宝,在網(wǎng)絡(luò)請(qǐng)求最后加上onErrorResumeNext(throwable -> getDisk())蛇受,這樣整個(gè)Rx流就不會(huì)結(jié)束,然后會(huì)轉(zhuǎn)到getDisk請(qǐng)求緩存數(shù)據(jù)的流中.
1厕鹃、如果不用onErrorResumeNext兢仰,當(dāng)網(wǎng)絡(luò)出問(wèn)題時(shí)候,請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)的流就會(huì)執(zhí)行OnError結(jié)束整個(gè)Rx流剂碴,然后我們必須在onError中在此發(fā)送請(qǐng)求緩存數(shù)據(jù)的Rx流把将,這樣比較麻煩了。
2忆矛、使用concat操作符察蹲,使用concat也是要等到請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)的Rx流執(zhí)行到OnError的時(shí)候,才能在次執(zhí)行請(qǐng)求緩存的Rx流催训,同樣比較麻煩.
不知道有沒(méi)有更好的方法洽议,如果有,希望留言漫拭,謝謝绞铃!
4、filter的一個(gè)錯(cuò)誤理解
由于沒(méi)有很好的理解filter嫂侍,以為filter過(guò)濾完所有數(shù)據(jù)(就是沒(méi)有得到自己想要的數(shù)據(jù))就會(huì)執(zhí)行subscribe的onError儿捧,其實(shí)正確的是 會(huì)直接執(zhí)行onComplete,然后整個(gè)流就結(jié)束了挑宠!
測(cè)試代碼:
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(null);
subscriber.onCompleted();
}
})
.filter(integer -> integer != null)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
LogUtils.i("integer:");
}
@Override
public void onError(Throwable e) {
LogUtils.i("integer:" + e.getMessage());
}
@Override
public void onNext(Integer integer) {
LogUtils.i("integer:" + integer);
}
});