這可能是最好的 RxJava 2.x 入門教程系列專欄
文章鏈接:
這可能是最好的 RxJava 2.x 入門教程(完結(jié)版)【重磅推出】
這可能是最好的 RxJava 2.x 入門教程(一)
這可能是最好的 RxJava 2.x 入門教程(二)
這可能是最好的 RxJava 2.x 入門教程(三)
這可能是最好的 RxJava 2.x 入門教程(四)
這可能是最好的 RxJava 2.x 入門教程(五)
GitHub 代碼同步更新:https://github.com/nanchen2251/RxJava2Examples
為了滿足大家的饑渴難耐箩张,GitHub 將同步更新代碼试浙,主要包含基本的代碼封裝怕轿,RxJava 2.x 所有操作符應(yīng)用場(chǎng)景介紹和實(shí)際應(yīng)用場(chǎng)景,后期除了 RxJava 可能還會(huì)增添其他東西寸宏,總之嗜愈,GitHub 上的 Demo 專為大家傾心打造凌净。傳送門:https://github.com/nanchen2251/RxJava2Examples
前言
最近很多小伙伴私信我赏胚,說(shuō)自己很懊惱,對(duì)于 RxJava 2.x 系列一看就能明白矾缓,但自己寫卻又寫不出來(lái)怀酷。如果 LZ 能放上實(shí)戰(zhàn)情景教程就最好不過(guò)了。也是哈嗜闻,單講我們的操作符胰坟,也讓我們的教程不溫不火,但 LZ 自己選擇的路泞辐,那跪著也要走完呀。所以竞滓,也就讓我可憐的小伙伴們?nèi)倘塘烁篮穑僮鞣R上就講完了。
正題
Single
顧名思義商佑,Single
只會(huì)接收一個(gè)參數(shù)锯茄,而 SingleObserver
只會(huì)調(diào)用 onError()
或者 onSuccess()
。
Single.just(new Random().nextInt())
.subscribe(new SingleObserver<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onSuccess(@NonNull Integer integer) {
mRxOperatorsText.append("single : onSuccess : "+integer+"\n");
Log.e(TAG, "single : onSuccess : "+integer+"\n" );
}
@Override
public void onError(@NonNull Throwable e) {
mRxOperatorsText.append("single : onError : "+e.getMessage()+"\n");
Log.e(TAG, "single : onError : "+e.getMessage()+"\n");
}
});
輸出:
distinct
去重操作符茶没,簡(jiǎn)單的作用就是去重肌幽。
Observable.just(1, 1, 1, 2, 2, 3, 4, 5)
.distinct()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("distinct : " + integer + "\n");
Log.e(TAG, "distinct : " + integer + "\n");
}
});
輸出:
很明顯,發(fā)射器發(fā)送的事件抓半,在接收的時(shí)候被去重了喂急。
debounce
去除發(fā)送頻率過(guò)快的項(xiàng),看起來(lái)好像沒(méi)啥用處笛求,但你信我廊移,后面絕對(duì)有地方很有用武之地糕簿。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Exception {
// send events with simulated time wait
emitter.onNext(1); // skip
Thread.sleep(400);
emitter.onNext(2); // deliver
Thread.sleep(505);
emitter.onNext(3); // skip
Thread.sleep(100);
emitter.onNext(4); // deliver
Thread.sleep(605);
emitter.onNext(5); // deliver
Thread.sleep(510);
emitter.onComplete();
}
}).debounce(500, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("debounce :" + integer + "\n");
Log.e(TAG,"debounce :" + integer + "\n");
}
});
輸出:
代碼很清晰,去除發(fā)送間隔時(shí)間小于 500 毫秒的發(fā)射事件狡孔,所以 1 和 3 被去掉了懂诗。
defer
簡(jiǎn)單地時(shí)候就是每次訂閱都會(huì)創(chuàng)建一個(gè)新的 Observable
,并且如果沒(méi)有被訂閱苗膝,就不會(huì)產(chǎn)生新的 Observable
殃恒。
Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> call() throws Exception {
return Observable.just(1, 2, 3);
}
});
observable.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Integer integer) {
mRxOperatorsText.append("defer : " + integer + "\n");
Log.e(TAG, "defer : " + integer + "\n");
}
@Override
public void onError(@NonNull Throwable e) {
mRxOperatorsText.append("defer : onError : " + e.getMessage() + "\n");
Log.e(TAG, "defer : onError : " + e.getMessage() + "\n");
}
@Override
public void onComplete() {
mRxOperatorsText.append("defer : onComplete\n");
Log.e(TAG, "defer : onComplete\n");
}
});
輸出:
last
last
操作符僅取出可觀察到的最后一個(gè)值,或者是滿足某些條件的最后一項(xiàng)辱揭。
Observable.just(1, 2, 3)
.last(4)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("last : " + integer + "\n");
Log.e(TAG, "last : " + integer + "\n");
}
});
輸出:
merge
merge
顧名思義离唐,熟悉版本控制工具的你一定不會(huì)不知道 merge 命令,而在 Rx 操作符中界阁,merge
的作用是把多個(gè) Observable
結(jié)合起來(lái)侯繁,接受可變參數(shù),也支持迭代器集合泡躯。注意它和 concat
的區(qū)別在于贮竟,不用等到 發(fā)射器 A 發(fā)送完所有的事件再進(jìn)行發(fā)射器 B 的發(fā)送。
Observable.merge(Observable.just(1, 2), Observable.just(3, 4, 5))
.subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("merge :" + integer + "\n");
Log.e(TAG, "accept: merge :" + integer + "\n" );
}
});
輸出:
reduce
reduce
操作符每次用一個(gè)方法處理一個(gè)值较剃,可以有一個(gè) seed
作為初始值咕别。
Observable.just(1, 2, 3)
.reduce(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
return integer + integer2;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("reduce : " + integer + "\n");
Log.e(TAG, "accept: reduce : " + integer + "\n");
}
});
輸出:
可以看到,代碼中写穴,我們中間采用 reduce 惰拱,支持一個(gè) function 為兩數(shù)值相加,所以應(yīng)該最后的值是:1 + 2 = 3 + 3 = 6 啊送, 而Log 日志完美解決了我們的問(wèn)題偿短。
scan
scan
操作符作用和上面的 reduce
一致,唯一區(qū)別是 reduce
是個(gè)只追求結(jié)果的壞人馋没,而 scan
會(huì)始終如一地把每一個(gè)步驟都輸出昔逗。
Observable.just(1, 2, 3)
.scan(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
return integer + integer2;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
mRxOperatorsText.append("scan " + integer + "\n");
Log.e(TAG, "accept: scan " + integer + "\n");
}
});
輸出:
看日志,沒(méi)毛病篷朵。
window
按照實(shí)際劃分窗口勾怒,將數(shù)據(jù)發(fā)送給不同的 Observable
mRxOperatorsText.append("window\n");
Log.e(TAG, "window\n");
Observable.interval(1, TimeUnit.SECONDS) // 間隔一秒發(fā)一次
.take(15) // 最多接收15個(gè)
.window(3, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Observable<Long>>() {
@Override
public void accept(@NonNull Observable<Long> longObservable) throws Exception {
mRxOperatorsText.append("Sub Divide begin...\n");
Log.e(TAG, "Sub Divide begin...\n");
longObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Long>() {
@Override
public void accept(@NonNull Long aLong) throws Exception {
mRxOperatorsText.append("Next:" + aLong + "\n");
Log.e(TAG, "Next:" + aLong + "\n");
}
});
}
});
輸出:
寫在最后
至此,大部分 RxJava 2.x 的操作符就告一段落了声旺,當(dāng)然還有一些沒(méi)有提到的操作符笔链,不是說(shuō)它們不重要,而是 LZ 也要考慮大家的情況腮猖,接下來(lái)就會(huì)根據(jù)實(shí)際應(yīng)用場(chǎng)景來(lái)對(duì) RxJava 2.x 發(fā)起沖鋒鉴扫。如果想看更多的數(shù)據(jù),請(qǐng)移步 GitHub:https://github.com/nanchen2251/RxJava2Examples
做不完的開(kāi)源澈缺,寫不完的矯情幔妨。歡迎掃描下方二維碼或者公眾號(hào)搜索「nanchen」關(guān)注我的微信公眾號(hào)鹦赎,目前多運(yùn)營(yíng) Android ,盡自己所能為你提升误堡。如果你喜歡古话,為我點(diǎn)贊分享吧~