問題1:檢視商品,先是獲取商品資料,然後獲取評論,然後。。。
解決手段:concat
詳解:
concat
:接收若干個Observables,將其組合並有序發射
程式碼
private void pay() {
Observable.concat(getGoods(), getComment()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Object o) {
System.out.println(o.toString());
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
}
});
}
private Observable<Object> getGoods() {
return Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Object> e) throws Exception {
// 獲取商品資料
System.out.println("獲取商品資料中");
Thread.sleep(3000);
e.onNext("我是商品資料");
// 注意,必須呼叫onComlete,否則下一個Observable不會執行
e.onComplete();
}
});
}
private Observable<Object> getComment() {
return Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Object> e) throws Exception {
// 獲取商品評論
System.out.println("獲取商品評論中");
Thread.sleep(3000);
e.onNext("我是商品評論");
e.onComplete();
}
});
}
複製程式碼
結果展示
問題1.1:登入,獲取userID,然後根據ID去請求。。。
解決手段:flatmap
詳解:
private void flatmap() {
login().flatMap(new Function<User, ObservableSource<Boolean>>() {
@Override
public ObservableSource<Boolean> apply(@NonNull User user) throws Exception {
System.out.println("使用者id" + user.uID);
return comment(user.uID);
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Boolean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Boolean o) {
System.out.println("評論" + o);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
複製程式碼
問題1.2:頁面資料需要請求幾個介面才能得到最終資訊。。。
解決手段:zip
詳解:
private void zip() {
Observable.zip(getComment(), getFromNet(), new BiFunction<Object, Integer, Object>() {
@Override
public Object apply(@NonNull Object o, @NonNull Integer integer) throws Exception {
System.out.println("中間合併分別是" + o.toString() + "和" + integer);
return o.toString() + integer;
}
}).subscribe(new Observer<Object>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Object o) {
System.out.println("結果" + o);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
複製程式碼
結論:concat和merge都是兩個Observable組合,每發射一次就會回撥一次,zip就是兩個Observable組合等兩個Observable都發射了才會回撥
問題2:展示一份資料,資料來源有本地快取以及網路獲取,首先檢視是否有快取,沒有則使用網路
解決手段:concat
、first
詳解:first
:只取第一個發射的資料
程式碼
private void getData() {
Observable.concat(getFromCache(),getFromNet()).first(1).subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onSuccess(@NonNull Integer integer) {
}
@Override
public void onError(@NonNull Throwable e) {
}
});
}
private Observable<Integer> getFromCache() {
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
if (hasCache) {
e.onNext(0);
}
e.onComplete();
}
});
}
private Observable<Integer> getFromNet() {
return Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
if (!hasCache) {
Thread.sleep(3000);
e.onNext(1);
}
e.onComplete();
}
});
}
複製程式碼
問題3:註冊頁面,需要所有資訊填寫完整,才能點選註冊
解決手段:combineLatest
詳解:combineLatest()
作用於最近發射的資料項:如果Observable1發射了A並且Observable2發射了B和C,combineLatest()將會分組處理AB和AC
程式碼
Observable<CharSequence> observableName = RxTextView.textChanges(((TextView) findViewById(R.id.text)));
Observable<CharSequence> observablePwd = RxTextView.textChanges(((TextView) findViewById(R.id.text)));
Observable<Boolean> observableEnd = Observable.combineLatest(observableName, observablePwd, new BiFunction<CharSequence,CharSequence,Boolean>() {
@Override
public Boolean apply(@NonNull CharSequence charSequence, @NonNull CharSequence charSequence2) throws Exception {
return charSequence.length() > 0 && charSequence2.length() > 0;
}
});
複製程式碼
問題4:資料來源需要進行篩選或者除null等過濾操作,不需要在結果再進行篩選,更專注與業務
解決手段:filter
程式碼
private void filter() {
Observable.fromArray("123","145",null,"3456").filter(new Predicate<String>() {
@Override
public boolean test(@NonNull String s) throws Exception {
// 這裡會過濾掉null值已經不是1開頭的字串
return !TextUtils.isEmpty(s) && s.startsWith("1");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull String s) {
System.out.println(s);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
複製程式碼