rxjava各類使用場景

1. 數據的三級緩存html

final Observable memory = Observable.create(new Observable.OnSubscribe() {
    @Override
    public void call(Subscriber super String> subscriber) {
        if (memoryCache != null) {
            subscriber.onNext(memoryCache);
        } else {
            subscriber.onCompleted();
        }
    }
});
Observable disk = Observable.create(new Observable.OnSubscribe() {
    @Override
    public void call(Subscriber super String> subscriber) {
        String cachePref = rxPreferences.getString("cache").get();
        if (!TextUtils.isEmpty(cachePref)) {
            subscriber.onNext(cachePref);
        } else {
            subscriber.onCompleted();
        }
    }
});

Observable network = Observable.just("network");

//主要就是靠concat operator來實現
Observable.concat(memory, disk, network)
.first()
.subscribeOn(Schedulers.newThread())
.subscribe(s -> {
    memoryCache = "memory";
    System.out.println("--------------subscribe: " + s);
});

取數據,首先檢查內存是否有緩存;而後檢查文件緩存中是否有;最後才從網絡中取;前面任何一個條件知足,就不會執行後面的java


2.界面須要等到多個接口併發取完數據,再更新

//拼接兩個Observable的輸出,不保證順序,按照事件產生的順序發送給訂閱者
private void testMerge() {
    Observable observable1 = DemoUtils.createObservable1().subscribeOn(Schedulers.newThread());
    Observable observable2 = DemoUtils.createObservable2().subscribeOn(Schedulers.newThread());

    Observable.merge(observable1, observable2)
            .subscribeOn(Schedulers.newThread())
            .subscribe(System.out::println);
}

3.一個接口的請求依賴另外一個API請求返回的數據

    舉個例子,咱們常常在須要登錄以後,根據拿到的token去獲取消息列表。react

    這裏用RxJava主要解決嵌套回調的問題,有一個專有名詞叫 Callback hellapi

NetworkService.getToken("username", "password")
    .flatMap(s -> NetworkService.getMessage(s))
    .subscribe(s -> {
        System.out.println("message: " + s);
    });
4. 界面按鈕須要防止連續點擊的狀況
RxView.clicks(findViewById(R.id.btn_throttle))
    .throttleFirst(1, TimeUnit.SECONDS)
    .subscribe(aVoid -> {
        System.out.println("click");
    });


5.響應式的界面
好比勾選了某個checkbox,自動更新對應的preference
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences);

Preference checked = rxPreferences.getBoolean("checked", true);

CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);
RxCompoundButton.checkedChanges(checkBox)
        .subscribe(checked.asAction());

6.複雜的數據變換
Observable.just("1", "2", "2", "3", "4", "5")
    .map(Integer::parseInt)
    .filter(s -> s > 1)
    .distinct()
    .take(3)
    .reduce((integer, integer2) -> integer.intValue() + integer2.intValue())
    .subscribe(System.out::println);//9


8.Netflix的真實例子

  a..假設咱們須要經過一個用戶的userId,執行queryA獲取他/她所關注的視頻列表,列表中的對象是Video類型對象,返回值是Json格式的string。緩存

  b.獲取了列表以後咱們只須要獲取前10個Video對象。網絡

  c.很是不幸的事情是,咱們獲取的Video對象不是一個完整的Video對象,queryA返回的值還缺乏了三個類成員->Rating, Metadata和BookMark.。因此咱們得經過Video對象的Id,call三個不一樣 api來獲取缺失的三個值,再講他們從新填入對應的Video對象。併發

那麼針對上面的需求咱們能夠整理一下思路,每一步究竟要作什麼:

 

Step1:經過userId獲取video的數據,這個時候咱們須要一個Observable<Video>ide

Step2:取前10個對象,這裏實現很簡單,take(10)足矣,依然是返回Observable<Video>。this

Step3:這一步須要咱們進行nested callback了,由於每個Video對象咱們都須要進行三個額外的API call,去獲取Rating,MetaData和Bookmark。可是這三個call都是同一時間進行的。因此咱們在這一步能夠經過flatmap把Step2裏面產生的Observable轉換成多個(分別是Observable, Observable 和 Observable),而且整合上述三個api call結果而且生成一個新的Observable<Video>返回。spa

Step4:在Step3中怎麼整合?試試zip() 這個操做符吧!簡單的說就是把若干不一樣的Obervable整合成一個Observable。好比咱們最終須要一個A對象,而後A由B和C對象組成,那麼假如咱們有一個Observable<B>和Observable<C>的話,就能夠把這兩個Observable zip一下整合成一個Observable<A>。


zip()

由於咱們須要將三個Api call的結果整合在一塊兒(Rating,MetaData,Bookmark)生成一個Video,因此咱們這裏選擇能夠用zip()。

咱們先上代碼,分別是Video類,VideoService類


video類

Video類的實現比較簡單,只是單純的加入了幾個class member。可是注意MetaData, BookMark, Rating這三個member是有getObservable方法的。

接下里是VideoService類


 

 

 

 

能夠看第一個方法是根據UserId返回原始Video對象的Observable,剩下三個則是根據videoId獲取bookmark,rating,metadata的Observable的方法。他們基本上都是差很少的。

那麼在定義好這些方法以後咱們要開始調用他們了,調用代碼以下:


開始啦

咱們挑重點一行行解釋

line 26 ->根據userID返回一個Observable<Video>,此時返回的video對象都是不完整的

line 28 ->只選取10個

line 30 ->這裏咱們須要返回一個新的Observable<Video>, 由 line 35- 37的三個Observable zip() 而成

line 39 - 53 ->三個子Observable互相zipWith(),每次zip都在原來video對象上填充須要的member。

line 57 -> 咱們在安卓的主線程裏面handle收到的新Video對象。

相關文章
相關標籤/搜索