說說RxJava在專案怎麼登的基

SamanLan發表於2017-12-13
問題1:檢視商品,先是獲取商品資料,然後獲取評論,然後。。。

解決手段:concat 詳解:

  1. 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:展示一份資料,資料來源有本地快取以及網路獲取,首先檢視是否有快取,沒有則使用網路

解決手段:concatfirst 詳解: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

combineLatest

程式碼

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() {

            }
        });
    }
複製程式碼

相關文章