目錄
基礎用法
使用步驟:
- 初始化 Observable
- 初始化 Observer
- 訂閱
當然不要忘了根據github地址添加依賴。
private static Observable<Integer> getObservable() {
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
Log.i(TAG, "subscribe: 發送 1 " + Thread.currentThread().getName());
observableEmitter.onNext(1);
Log.i(TAG, "subscribe: 發送 2 " + Thread.currentThread().getName());
observableEmitter.onNext(2);
Log.i(TAG, "subscribe: 發送 3 " + Thread.currentThread().getName());
observableEmitter.onNext(3);
Log.i(TAG, "subscribe: 發送 4 " + Thread.currentThread().getName());
observableEmitter.onNext(4);
}
});
}
public static void step1() {
// 1.初始化Obervable
Observable<Integer> observable = getObservable();
// 2.初始化Observer
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable disposable) {
mDisposable = disposable;
}
@Override
public void onNext(Integer integer) {
Log.i(TAG, "onNext: 接收數據" + integer);
if (integer == 3) {
Log.i(TAG, "onNext: 主動銷燬數據" + integer);
mDisposable.dispose();
}
}
@Override
public void onError(Throwable throwable) {
Log.i(TAG, "onError: 錯誤數據" + throwable.getMessage());
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete: 完成");
}
};
// 3.創建訂閱關係
observable.subscribe(observer);
}
線程調度
subscribeOn:指定被訂閱數據線程,即發送數據上游線程。多次調用僅第一次有效。
observeOn:指定觀察者線程,即接收數據下游線程。多次調用多次生效,根據最近一次調用調度線程。
public static void scheduler() {
Observable<Integer> observable = getObservable();
observable
.subscribeOn(AndroidSchedulers.mainThread()) // 主線程發射數據
.subscribeOn(Schedulers.newThread()) // 子線程發射數據
.subscribeOn(Schedulers.io()) // io線程發射數據
.observeOn(AndroidSchedulers.mainThread()) // 主線程接收數據
.doOnNext(new Consumer<Integer>() { // 在accept之前調用
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: AndroidSchedulers.mainThread() 當前線程" + Thread.currentThread().getName());
Log.i(TAG, "accept: AndroidSchedulers.mainThread() 接收數據" + integer);
}
})
.observeOn(Schedulers.io()) // io線程接收數據
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: AndroidSchedulers.io() 當前線程" + Thread.currentThread().getName());
Log.i(TAG, "accept: AndroidSchedulers.io() 接收數據" + integer);
}
});
}
doOnNext:在下游接收數據前調用。onNext()之前。
doAfterNext:在接收數據之後調用。onNext()之後。
關鍵字
create
產生一個 Obserable
被觀察者對象,即上游發射器。
map
將發射出來的數據一一映射處理一遍。
public static void map() {
Observable<Integer> observable = getObservable();
// 將 int --> String
observable.map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "map " + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: ==" + s);
}
});
}
flatMap/concatMap
將一組上游發射數據轉換爲N個Observable,之後無序/有序的發射這N個發射器的數據。
public static void flatMap() {
getIntObservable()
.flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < integer; i++) {
list.add("第" + integer + "波數據:" + i);
}
return Observable.fromIterable(list).delay(3-integer, TimeUnit.SECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: 接收數據 " + s);
}
});
}
timer
定時任務。訂閱後延時多久開始發射數據。
public static void timer() {
final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Log.i(TAG, "timer: 開始時間 " + dateFormat.format(System.currentTimeMillis()));
Observable.timer(2,TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.i(TAG, "timer: 結束時間 " + dateFormat.format(System.currentTimeMillis()));
}
});
}
interval
計時任務。每隔一段時間發射一次數據。
延遲1s後開始計時,每次間隔1s,5s後標記任務爲處理狀態。
public static void interval() {
final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Log.i(TAG, "timer: 開始時間 " + dateFormat.format(System.currentTimeMillis()));
Disposable disposable = Observable.interval(1, 1, TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
Log.i(TAG, "timer: 計時 " + dateFormat.format(System.currentTimeMillis()));
}
});
try {
Thread.sleep(5000);
disposable.dispose();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
zip
將兩個或以上發射器數據合併在一起,按一一對應方式合併,所以最終結果是按照最小數量發射器,多的數據直接捨棄。從下例可以看出結果只能到 " three is 3" ,"four" 被捨棄了。
public static void zip() {
Observable.zip(getIntObservable(), getStringObservable(),
new BiFunction<Integer, String, String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return s + " is " + integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: " + s);
}
});
}
private static Observable<Integer> getIntObservable() {
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
// Log.i(TAG, "subscribe: 發送 1 " + Thread.currentThread().getName());
observableEmitter.onNext(1);
// Log.i(TAG, "subscribe: 發送 2 " + Thread.currentThread().getName());
observableEmitter.onNext(2);
// Log.i(TAG, "subscribe: 發送 3 " + Thread.currentThread().getName());
observableEmitter.onNext(3);
// 通知下游數據發送完成 後續數據不在接收
observableEmitter.onComplete();
// Log.i(TAG, "subscribe: 發送 4 " + Thread.currentThread().getName());
observableEmitter.onNext(4);
}
});
}
private static Observable<String> getStringObservable() {
return Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("one");
observableEmitter.onNext("two");
observableEmitter.onNext("three");
observableEmitter.onNext("four");
// 通知下游數據發送完成 後續數據不在接收
observableEmitter.onComplete();
}
});
}
concat/merge
將兩個上游發射器合併在一起,按照順序依次發送數據/無序發送數據。合併的observable的數據類型必須相同。
public static void concat(){
Observable.concat(getIntObservable(),getIntObservable())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
}
從結果可以看concat出是在第一個observable之後有序發射第二個observable的數據。
distinct
去重,去除重複的數據。
class DistinctBean {
String name;
int id;
public DistinctBean(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "DistinctBean{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DistinctBean)) return false;
DistinctBean that = (DistinctBean) o;
return id == that.id &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
}
private static Observable<DistinctBean> getDistinctObservable() {
return Observable.create(new ObservableOnSubscribe<DistinctBean>() {
@Override
public void subscribe(ObservableEmitter<DistinctBean> observableEmitter) throws Exception {
observableEmitter.onNext(new DistinctBean("a", 1));
observableEmitter.onNext(new DistinctBean("b", 1));
observableEmitter.onNext(new DistinctBean("b", 1));
observableEmitter.onNext(new DistinctBean("b", 2));
// 通知下游數據發送完成 後續數據不在接收
observableEmitter.onComplete();
}
});
}
1.不指定key,直接進行對象比較,過濾掉一個數據 {b,1}
getDistinctObservable().distinct()
.subscribe(new Consumer<DistinctBean>() {
@Override
public void accept(DistinctBean distinctBean) throws Exception {
Log.i(TAG, "accept: " + distinctBean.toString());
}
});
2.指定比較的key是name字段,過濾掉後兩個數據
getDistinctObservable().distinct(new Function<DistinctBean, String>() {
@Override
public String apply(DistinctBean distinctBean) throws Exception {
return distinctBean.name;
}
}).subscribe(new Consumer<DistinctBean>() {
@Override
public void accept(DistinctBean distinctBean) throws Exception {
Log.i(TAG, "accept: " + distinctBean.toString());
}
});
filter
根據條件過濾掉無用數據。
public static void filter(){
getDistinctObservable().filter(new Predicate<DistinctBean>() {
@Override
public boolean test(DistinctBean distinctBean) throws Exception {
// true 通過篩選
return "b".equals(distinctBean.name);
}
}).subscribe(new Consumer<DistinctBean>() {
@Override
public void accept(DistinctBean distinctBean) throws Exception {
Log.i(TAG, "accept: " + distinctBean.toString());
}
});
}
buffer
分組截取,將上游發射器數據分組,新的發射器每次發射一組數據。
下例,每次遊標滑動4,然後取後面的3個數爲一個List發射。
結果爲:[1,2,3] [5,6,7]
public static void buffer() {
Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
.buffer(3, 4)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
Log.i(TAG, "accept: " + integers.toString());
}
});
}
skip/skipLast
捨棄一些數據後開始接收數據。從前/從後
public static void skip(){
Observable.just(1,2,3,4,5)
.skipLast(2)
// .skip(2)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
}
take/takeLast
只接收一定量的數據。從前/從後
public static void take(){
Observable.just(1,2,3,4,5,6)
.take(2)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 結果 1 2
}
});
}
single
單個數據發射器。SingleObserver只回調onSuccess和onError。
public static void single(){
Single.just(1)
.subscribe(new SingleObserver<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(Integer integer) {
Log.i(TAG, "onSuccess: " + integer);
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError: ");
}
});
}
debounce/ThrottleWithTimeout
去抖動,覆蓋掉間隔過短的數據,即有效數據爲短間隔的後一個數據。
public static void debounce() {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1); // 被覆蓋
Thread.sleep(200);
emitter.onNext(2); // 接收
Thread.sleep(600);
emitter.onNext(3); // 被覆蓋
Thread.sleep(300);
emitter.onNext(4); // 被覆蓋
Thread.sleep(300);
emitter.onNext(5); // 接收
}
}).throttleWithTimeout(400, TimeUnit.MILLISECONDS)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 結果 2 5
}
});
}
last
只接收最後一個數據,當沒有數據時,發射傳入的默認值。
public static void last() {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onComplete();
}
}).last(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 結果 3
}
});
}
reduce/scan
將數據按照方法依次兩兩操作,可以設置一個初始值。
reduce只關注結果的一次數據。
scan每一步的數據都發射一次。seed也會發射一次。
public static void reduce(){
Observable.just(1,2,3,4)
.reduce(2, new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
return integer + integer2;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer); // 結果 12 scan結果:2 3 5 8 12
}
});
}