RxJava2的使用
特別感謝:
南塵2251的部落格
Rxjava最近使用的時候有很多不記得的了,所以說一定要寫一篇部落格記錄一下,好了廢話不多說,快上車吧!
關聯類庫,這個是最重要的!
compile 'io.reactivex.rxjava2:rxjava:2.1.2'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
瞭解操作符:
關於RxJava的操作符,我們還要一個一個的說,哎挺頭疼的...哈哈!
Create操作符
這個操作符其實就是一個建立的操作符,這個也是最基本的一個操作符:最基本的寫法,上面已經寫了很多的註釋,基本上都能看明白的!
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
e.onNext("a");
e.onNext("b");
e.onNext("c");
e.onNext("d");
e.onComplete();/*結束的操作符*/
}
});
observable.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
/*開始的時候執行*/
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull String s) {
/*onNext呼叫的時候執行*/
Log.e(TAG, "onNext: " + s);
mTvContent.setText(s);
}
@Override
public void onError(@NonNull Throwable e) {
/*錯誤的時候執行*/
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
/*complete的時候執行,也就是最後的時候執行*/
Log.e(TAG, "onComplete: ");
}
});
這裡面有一點要說明的,如果你在b和c中間的時候呼叫e.onComplete();
那麼c和d就不會執行的!這裡記住!!!只要是onComplete()呼叫的話就會終止這次操作!
just操作符
就是傳送一個指定內容的操作符
Observable.just(1, 2, 3, 4, 5)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
Map操作符
這個操作符你可以理解為每傳送一個資料,我攔截一下,做出改變之後再傳送出去。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onNext("4");
e.onComplete();
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(@NonNull String s) throws Exception {
return Integer.valueOf(s) * 10;
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
mTvContent.setText(String.valueOf(integer));
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這個map的操作符裡面是一個Function這個類,傳入的泛型這裡說明一下,前一個是Observable傳送型別的泛型,後面那個是你想改變之後型別的泛型,之後接收的時候Observer會把型別自動轉換成後面那個泛型的型別!(說的有點白話,但是我覺得這樣比較好理解,嘻嘻)
Zip操作符
這個操作符就是和Windows的zip檔案似的,就是把兩個Observable進行合併!打成一個包!(但是這裡有一點要注意,兩個數量不同的Observable合併的時候是以最少的為準,很好理解,就是一個多的一個說的兩兩配對,沒有配對的就捨去了唄!單身狗的悲哀)
/*傳送字串的Observable*/
Observable<String> mStringObservable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onNext("4");
e.onNext("5");
e.onComplete();
}
});
/*傳送數字的Observable*/
Observable<Integer> mIntObservable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
e.onNext(4);
e.onNext(5);
e.onNext(6);
e.onComplete();
}
});
Observable.zip(mStringObservable, mIntObservable, new BiFunction<String, Integer, String>() {
@Override
public String apply(@NonNull String s, @NonNull Integer integer) throws Exception {
return String.valueOf(Integer.valueOf(s) + integer);
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull String s) {
Log.e(TAG, "onNext: " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這裡有幾點說明的,那個BiFunction類中傳入的泛型,第一個和第二個是兩個要合併操作符的兩個泛型,第三個是合併之後的泛型,zip的操作符中間的是合併的規則,最後那個Observer的泛型會和合並之後的泛型相同的!列印結果的話就能看出來是以最少的那個數量為標準!
Concat操作符
這個操作符是把兩個Observable合成一個Observable的操作符
Observable.concat(Observable.just(1, 2, 3), Observable.just(4, 5, 6))
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這裡說明下就是要合併的兩個操作符應該屬於同一型別的,並且是按照順序進行排列的。
FlatMap操作符的使用
就是將一個Observable轉換成多個Observable進行傳送,然後把多個Observable裝進一個發射器中進行傳送,FlatMap不能保證順序,這點一定要切記!
Observable.just(1, 2, 3, 4)
.flatMap(new Function<Integer, ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> apply(@NonNull Integer integer) throws Exception {
List<Integer> mList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
mList.add(i);
}
return Observable.fromIterable(mList);
}
})
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這裡簡單說下邏輯,就是傳送1到4四個資料,之後每一個都轉換成0到4四個資料列印出來。但是這裡注意一點就是使用FlatMap的時候,傳入第二個引數(Observable的時候一定要指定一個泛型,這個泛型一定是之後Observer的時候轉換的泛型,切記切記!!!)
這裡面雖然看不出順序問題,但是你一定要記得這中間有這麼個問題!
concatMap和FlatMap操作符唯一的區別就是能保證順序,就不再這裡寫出程式碼來了!
distinct操作符
去除重複的操作符
Observable.just(1, 2, 3, 4, 3, 2, 1)
.distinct()
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這個是從前面開始,如果之後有重複的話就不會傳送了!
Filter操作符
過濾操作符,你自己指定一個規定,自己過濾掉不想要的就可以了
Observable.just(12, 53, 34, 21, 18, 20, 39)
.filter(new AppendOnlyLinkedArrayList.NonThrowingPredicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer >30;
}
})
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這裡面filter過濾的時候會傳入一個物件,這個物件可以是AppendOnlyLinkedArrayList.NonThrowingPredicate或者是Predicate結果都是一樣的,什麼區別我還真的不知道,希望哪位大神幫忙講解下,謝謝!接著說其實這裡面就是返回一個過濾的方法,結果是true和false,從而進行過濾!
buffef操作符
這個操作符是buffef(count,skip)這樣的,作用就是把一個Observable按照你指定的數量count每次Observable從中取出count個元素,每一個Observable是裡面包含count個專案(如果個數夠的話,不夠的話就取剩下的),這裡要說明一下,count是代表每次取出的數量,skip是步長(也就是每次跳過的個數)。
Observable.just(1, 2, 3, 4, 5, 6)
.buffer(3, 2)
.subscribe(new Observer<List<Integer>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull List<Integer> integers) {
Log.e(TAG, "onNext: " + integers);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
說明一下這個列印結果:首先從just中取出3個也就是count個個數,傳送有一個Observable,然後跳過2個也就是skip繼續取count個元素髮送一個Observable,依次取,最後一個由於只有兩個了,所以只取了2個
timer操作符
首先說明一下在2.0當中timer已經變成一個定時任務了,就是傳送一個指定(延遲)時間的請求,而不再是執行間隔邏輯了,間隔邏輯已經被interval取代了,下面會進行講解的!
Observable.timer(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())/*發生的執行緒*/
.observeOn(AndroidSchedulers.mainThread())/*回撥的執行緒*/
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Long aLong) {
Log.e(TAG, "onNext: " + String.valueOf(aLong));
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
注意一點問題:就是timer會建立一個新的執行緒去執行!
interval操作符
這個操作符就相當於一個定時的請求了,會一直執行的
Observable.interval(1, 1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Long aLong) {
Log.e(TAG, "onNext: " + String.valueOf(aLong));
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
如果想要停止的話可以使用Disposable 這個物件的dispose()方法
doOnNext操作符
其實它不算做操作符,只是比較常用
它的作用是讓訂閱者在接收到資料之前乾點有意思的事情。假如我們在獲取到資料之前想先儲存一下它,我們可以這樣實現。
Observable.just(1, 2, 3, 4, 5)
.doOnNext(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.e(TAG, "doOnNext: 這裡做一些操作就可以了");
}
})
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
其實就是在每次傳送之前先走doOnNext方法進行一些操作,它會在onNext之前呼叫。
skip操作符
這個操作符其實就是跳過多少個條目之後執行,沒有什麼好說的,看一下列印結果就可以了!
Observable.just(1, 2, 3, 4, 5, 6, 7)
.skip(3)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
take操作符
take操作符的作用就是最多能接受多少個引數,這個是從頭開始來的。
Observable.just(1, 2, 3, 4, 5, 6, 7)
.take(4)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
debounce操作符
這個操作符的作用就是去掉髮送頻率過快的項
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
e.onNext("1");// skip
Thread.sleep(400);
e.onNext("2"); // deliver
Thread.sleep(505);
e.onNext("3"); // skip
Thread.sleep(100);
e.onNext("4"); // deliver
Thread.sleep(605);
e.onNext("5"); // deliver
Thread.sleep(510);
e.onComplete();
}
})
.debounce(500, TimeUnit.MILLISECONDS)
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull String s) {
Log.e(TAG, "onNext: " + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: " + e);
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
這個操作符還是要說一下的!他是去除傳送較為頻繁的項,這裡指定的是500毫秒,所以就把傳送在500毫秒以內的全部清除掉了。
defer操作符
這個操作符的作用就是把之前的Observable轉換成一個新的Observable傳送出來,如果沒有的話他就不傳送了,我是這麼理解的!
Observable.defer(new Callable<ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> call() throws Exception {
return Observable.just(1, 2, 3);
}
})
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e(TAG, "onSubscribe: ");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.e(TAG, "onNext: " + integer);
}
@Override
public void onError(@NonNull Throwable e) {
Log.e(TAG, "onError: ");
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
last操作符
這個操作符是獲取最後一個傳送項
Observable.just(1,2,3,4,5)
.last(1)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.e(TAG, "accept: " + integer);
}
});
其實這裡我測試過,這個last後面的引數如論傳入多少獲取的都是最後一項,寫得是預設的條目,這裡我還是不太理解,希望理解的大神說一下!
merge操作符
這個操作符的作用就是合併兩個Observable
Observable.merge(Observable.just(1, 2, 3), Observable.just(4, 5, 6))
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.e(TAG, "accept: " + integer);
}
});
reduce操作符
每次用一個方法處理一個值,可以有一個 seed 作為初始值。
其實這個操作符的理解就是用一個方法把兩個物件操作一下,然後合成了一個物件在操作一下,最後返回了一個物件.
Observable.just(1, 2, 3, 4, 5, 6)
.reduce(10, 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(Integer integer) throws Exception {
Log.e(TAG, "accept: " + integer);
}
});
這裡還是說明一下,這個呢就是傳送1到6,6個數字,但是中間經過了reduce方法之後,使得這一次的結果和上次的結果進行相加,前面那個10 是一個初始值。
scan操作符
其實這個操作符和上面的reduce操作符類似,但是不同的是他會把每一個步驟都列印出來,而reduce只會列印結果
Observable.just(1, 2, 3, 4, 5, 6)
.scan(10, 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(Integer integer) throws Exception {
Log.e(TAG, "accept: " + integer);
}
});
程式碼都差不多,只是列印結果略有不同
基本上的操作符就講到這裡吧!我也是能力有限,寫一半加深一下自己的印象,也希望對其他朋友有幫助!!!
下次就看看實際專案中怎麼用吧!!!
Demo地址
相關文章
- Rxjava2與Retrofit2的使用RxJava
- RxJava2 系列-3:使用 SubjectRxJava
- 史上最全的Rxjava2講解(使用篇)RxJava
- 使用RxJava2 + Retrofit 報錯DuplicateFileExceptionRxJavaException
- Rxjava2(一)、基礎概念及使用RxJava
- Rxjava2的簡單使用與基本操作符RxJava
- RxJava2 系列-1:一篇的比較全面的 RxJava2 方法總結RxJava
- RxJava2 學習(一)RxJava
- RxJava2 學習(二)RxJava
- RxJava2原始碼分析RxJava原始碼
- 圖解RxJava2(二)圖解RxJava
- RxJava2 原始碼解析(一)RxJava原始碼
- Rxjava2最全面的解析RxJava
- Rxjava2解析-訂閱流程RxJava
- RxJava2 原始碼解析(二)RxJava原始碼
- Rxjava2操作符(二)RxJava
- RxJava2輕鬆入門RxJava
- Rxjava2操作符(三)RxJava
- Rxjava1升級到Rxjava2的工作RxJava
- 網路庫與Rxjava2結合常見使用場景介紹RxJava
- 深入理解 RxJava2:Scheduler(2)RxJava
- 深入RxJava2 原始碼解析(一)RxJava原始碼
- RxJava2 中 doFinally 和 doAfterTerminRxJava
- 深入RxJava2 原始碼解析(二)RxJava原始碼
- RxJava2 操作符總結RxJava
- RxJava2主題v5RxJava
- 詳解 RxJava2 的執行緒切換原理RxJava執行緒
- RxJava2與RxJava1的簡單對比RxJava
- RxJava2 錯誤處理詳解RxJava
- RxJava2系列之背壓策略(一)RxJava
- RxJava2 系列-2:背壓和FlowableRxJava
- 深入理解 RxJava2:前世今生(1)RxJava
- Android——RxJava2史上最全講解AndroidRxJava
- Rxjava2操作符入門(一)RxJava
- RxJava2 原始碼解析及設計思想RxJava原始碼
- RxJava2原始碼分析(一):基本流程分析RxJava原始碼
- RxJava2操作符學習筆記RxJava筆記
- RxJava1 升級到 RxJava2 所踩過的坑RxJava