RxAndroid 學習和操作符的理解
RxJava 的觀察者模式
1)RxJava 有四個基本概念:Observable (可觀察者,即被觀察者)、 Observer (觀察者)、 subscribe (訂閱)、事件。Observable 和 Observer 通過 subscribe() 方法實現訂閱關係,從而 Observable 可以在需要的時候發出事件來通知 Observer。
2)與傳統觀察者模式不同, RxJava 的事件回撥方法除了普通事件 onNext() (相當於 onClick() / onEvent())之外,還定義了兩個特殊的事件:onCompleted() 和 onError()。
3)onCompleted(): 事件佇列完結。RxJava 不僅把每個事件單獨處理,還會把它們看做一個佇列。RxJava 規定,當不會再有新的 onNext() 發出時,需要觸發 onCompleted() 方法作為標誌。
4)onError(): 事件佇列異常。在事件處理過程中出異常時,onError() 會被觸發,同時佇列自動終止,不允許再有事件發出。
5)在一個正確執行的事件序列中, onCompleted() 和 onError() 有且只有一個,並且是事件序列中的最後一個。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在佇列中呼叫了其中一個,就不應該再呼叫另一個。
上游可以傳送無限個onNext, 下游也可以接收無限個onNext. 當上遊傳送了一個onComplete後, 上游onComplete之後的事件將會繼續傳送, 而下游收到onComplete事件之後將不再繼續接收事件. 當上遊傳送了一個onError後, 上游onError之後的事件將繼續傳送, 而下游收到onError事件之後將不再繼續接收事件. 上游可以不傳送onComplete或onError. 最為關鍵的是onComplete和onError必須唯一併且互斥, 即不能發多個onComplete, 也不能發多個onError, 也不能先發一個onComplete, 然後再發一個onError
RxJava多執行緒選項
name | 說明 |
---|---|
Schedulers.io() | 代表io操作的執行緒, 通常用於網路,讀寫檔案等io密集型的操作 |
Schedulers.computation() | 代表CPU計算密集型的操作, 即不會被 I/O 等操作限制效能的操作,例如圖形的計算。這個 Scheduler 使用的固定的執行緒池,大小為 CPU 核數。不要把 I/O 操作放在 computation() 中,否則 I/O 操作的等待時間會浪費 CPU。 |
Schedulers.newThread() | 代表一個常規的新執行緒 |
AndroidSchedulers.mainThread() | 代表Android的主執行緒 |
newThread() 差不多,區別在於 io() 的內部實現是是用一個無數量上限的執行緒池,可以重用空閒的執行緒,因此多數情況下 io() 比 newThread() 更有效率。不要把計算工作放在 io() 中,可以避免建立不必要的執行緒。
建立一個普通的
private void create() {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.e(TAG, "emit 1");
emitter.onNext(1);
Log.e(TAG, "emit 2");
emitter.onNext(2);
Log.e(TAG, "emit 3");
emitter.onNext(3);
Log.e(TAG, "emit complete");
emitter.onComplete();
Log.e(TAG, "emit 4");
emitter.onNext(4);
}
}).subscribe(new Observer<Integer>() {
private Disposable mDisposable;
private int i;
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "subscribe");
mDisposable = d;
}
@Override
public void onNext(Integer value) {
Log.e(TAG, "onNext: " + value);
i++;
if (i == 2) {
Log.e(TAG, "dispose");
mDisposable.dispose();
Log.e(TAG, "isDisposed : " + mDisposable.isDisposed());
}
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "error");
}
@Override
public void onComplete() {
Log.e(TAG, "complete");
}
});
}
複製程式碼
使用just時,just是將資料作為一個完整的物件一次性發射的,最後呼叫的fromArray map 是一個變形的過程eg 由△--->口
private void just() {
String[] students = {"jay", "tom"};
String[] students22 = {"jay22", "tom22"};
//------------------對兩個陣列進行合併後一次性發出------------------------
Observable.just(students, students22).subscribe(new Consumer<String[]>() {
@Override
public void accept(String[] strings) throws Exception {
for (String s : strings) {
Log.e(TAG, "1=just===" + s);
}
}
});
Observable observable1 = Observable.just("100", "2000").map(new Function<String, Object>() {
@Override
public Integer apply(String s) throws Exception {
return Integer.parseInt(s);
}
});
observable1.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.e(TAG, "1====" + integer);
}
});
//---------------------------------------------------
Observable<String> observable2 = Observable.just(students).map(new Function<String[], String>() {
@Override
public String apply(String[] strings) throws Exception {
String str = "";
for (String s : strings) {
str = str + s;
}
return str;
}
});
observable2.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, "observable2==" + s);
}
});
//==============================================
Observable observable = Observable.just(students, students22).map(new Function<String[], String>() {
@Override
public String apply(String[] strings) throws Exception {
String str = "";
for (String s : strings) {
str = str + s;
}
return str;
}
});
observable.subscribe(new Consumer<String>() {
@Override
public void accept(String strings) throws Exception {
Log.e(TAG, "222===" + strings);
}
});
}
複製程式碼
使用fromArray接收的資料來源是逐個發射的
private void fromArray() {
String[] students = {"jay", "tom"};
Observable.fromArray(students).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.e(TAG, s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
複製程式碼
map 是一個變形的過程eg 由△--->口 由String --->Integer
private void map() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("111111");
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return Integer.parseInt(s);
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
Log.e(TAG, "map===" + s);
}
});
}
複製程式碼
concatMap它和flatMap的作用幾乎一模一樣, 只是它的結果是嚴格按照上游傳送的順序來傳送的, flatMap並不保證事件的順序
private void flatMap() {
// concatMap它和flatMap的作用幾乎一模一樣, 只是它的結果是嚴格按照上游傳送的順序來傳送的, flatMap並不保證事件的順序
Disposable subscribe = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(7);
emitter.onNext(8);
emitter.onNext(9);
}
}).flatMap(new Function<Integer, ObservableSource<List<String>>>() {
@Override
public ObservableSource<List<String>> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("I am value " + integer);
}
return Observable.just(list);
}
}).flatMap(new Function<List<String>, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(List<String> strings) throws Exception {
String str = strings.toString();
return Observable.just(str);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
mBtnStart.setText(s.toString());
}
});
}
複製程式碼
Zip通過一個函式將多個Observable傳送的事件結合到一起,然後傳送這些組合到一起的事件. 它按照嚴格的順序應用這個函式。它只發射與發射資料項最少的那個Observable一樣多的資料。
private void zip() {
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
for (int i = 0; ; i++) {
e.onNext(i);
// Thread.sleep(1000);
}
}
}).subscribeOn(Schedulers.io());
Observable observable2 = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
Thread.sleep(2000);
e.onNext("B");
Thread.sleep(2000);
e.onNext("C");
Thread.sleep(2000);
}
}).subscribeOn(Schedulers.io());
Observable.zip(observable, observable2, new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer o, String o2) throws Exception {
return o + o2;
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
mBtnStart.setText(s);
}
});
}
複製程式碼
上下流分配(借鑑Season_zlc)
我們把上游看成小日本, 把下游當作葉問, 當呼叫Subscription.request(1)時, 葉問就說我要打一個!
然後小日本就拿出一個鬼子給葉問, 讓他打, 等葉問打死這個鬼子之後, 再次呼叫request(10),
葉問就又說我要打十個! 然後小日本又派出十個鬼子給葉問, 然後就在邊上看熱鬧, 看葉問能不能打死十個鬼子,
等葉問打死十個鬼子後再繼續要鬼子接著打...
複製程式碼
private void fLowable() {
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
for (int i = 0; i < 128; i++) {
Log.d(TAG, "emit " + i);
emitter.onNext(i);
}
}
}, BackpressureStrategy.ERROR)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Integer>() {
@Override
public void onSubscribe(Subscription s) {
subscription = s;
s.request(1);// 每次從水缸裡去取一個
}
@Override
public void onNext(Integer integer) {
mBtnStart.setText("第" + integer + "個");
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
複製程式碼
DOME下載 歡迎Start Star 我的GitHub