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>。
由於咱們須要將三個Api call的結果整合在一塊兒(Rating,MetaData,Bookmark)生成一個Video,因此咱們這裏選擇能夠用zip()。
咱們先上代碼,分別是Video類,VideoService類
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對象。