RxJava2.0學習筆記

  • 第一步:創建被觀察者(observable)
        Observable<Integer> observable = Observable.create(new  ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
                emitter.onComplete();
                //ObservableEmitter為事件的發射器
            }
        });
  • 第二步 創建觀察者(observer)
        Observer<Integer> observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d("a","subscribe");
            }

            @Override
            public void onNext(Integer integer) {
                Log.d("a",""+integer);
            }

            @Override
            public void onError(Throwable e) {
                Log.d("a","error");
            }

            @Override
            public void onComplete() {
                Log.d("a","complete");
            }
        };
        
  • 被觀察者與觀察者建立聯系

    observable.subscribe(observer);

  • Rxjava的鏈式操作

            Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws            Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "subscribe");
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "" + value);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "error");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "complete");
            }
        });
        
  • RxJava的異步和鏈式編程
    異步操作需要調用observeOn(AndroidSchedulers.mainThread()),observeOn是事件回調的線程,

    AndroidSchedulers.mainThread()一看就知道是主線程,
    subscribeOn(Schedulers.io()),subscribeOn是事件執行的線程,Schedulers.io()是子線程,這里也可以用Schedulers.newThread(),只不過io線程可以重用空閑的線程,因此多數情況下 io()比newThread() 更有效率。

簡單的來說, subscribeOn() 指定的是上游發送事件的線程, observeOn() 指定的是下游接收事件的線程.

      Observable.create(new ObservableOnSubscribe<String>() {
          @Override
          public void subscribe(ObservableEmitter<String> emitter) throws Exception {
              emitter.onNext("連載1");
              emitter.onNext("連載2");
              emitter.onNext("連載3");
              emitter.onComplete();
          }
      })
              .observeOn(AndroidSchedulers.mainThread())//回調在主線程
              .subscribeOn(Schedulers.io())//執行在io線程
              .subscribe(new Observer<String>() {
                  @Override
                  public void onSubscribe(Disposable d) {
                      Log.e(TAG,"onSubscribe");
                  }

                  @Override
                  public void onNext(String value) {
                      Log.e(TAG,"onNext:"+value);
                  }

                  @Override
                  public void onError(Throwable e) {
                      Log.e(TAG,"onError="+e.getMessage());
                  }

                  @Override
                  public void onComplete() {
                      Log.e(TAG,"onComplete()");
                  }
              });
  • 異步的舉例2
    沒有任何嵌套,邏輯依然簡潔
       Observable.create(new ObservableOnSubscribe<Drawable>() {
           @Override
           public void subscribe(ObservableEmitter<Drawable> emitter) throws Exception {
               for (int i=0;i<drawableRes.length;i++){
                   Drawable drawable=getResources().getDrawable(drawableRes[i]);
                   //第6個圖片延時3秒后架子
                   if (i==5){
                       sleep(3000);
                   }
                   //復制第7張圖片到sd卡
                   if (i==6){
                       Bitmap bitmap=((BitmapDrawable)drawable).getBitmap();
                       saveBitmap(bitmap,"test.png", Bitmap.CompressFormat.PNG);
                   }
                   //上傳到網絡
                   if (i==7){
                       updateIcon(drawable);
                   }
                   emitter.onNext(drawable);
               }
           }
       }).subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(new Consumer<Drawable>() {
                   @Override
                   public void accept(Drawable drawable) throws Exception {
                          //回調后在UI界面上展示出來
                   }
               });
  • 關于上下游所在線程的問題
    多次指定上游的線程只有第一次指定的有效, 也就是說多次調用subscribeOn() 只有第一次的有效, 其余的會被忽略.

多次指定下游的線程是可以的, 也就是說每調用一次observeOn() , 下游的線程就會切換一次.

舉個例子:

    observable.subscribeOn(Schedulers.newThread())     
         .subscribeOn(Schedulers.io())              
         .observeOn(AndroidSchedulers.mainThread()) 
         .observeOn(Schedulers.io())                
         .subscribe(consumer);
  • 操作符

    • Map
            
            Observable.create(new ObservableOnSubscribe<Integer>() {
           @Override
           public void subscribe(ObservableEmitter<Integer> emitter) throws               Exception {
               emitter.onNext(1);
               emitter.onNext(2);
               emitter.onNext(3);
           }
           }).map(new Function<Integer, String>() {
           @Override
           public String apply(Integer integer) throws Exception {
               return "This is result " + integer;
           }
           }).subscribe(new Consumer<String>() {
           @Override
           public void accept(String s) throws Exception {
               Log.d(TAG, s);
           }
           });
           
      
    將上游的Integer類型數據轉化為下游的字符串類型
    
  • flatMap
    下游輸出數據無序性

  • concatMap 下游數據數據有序

         Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("I am value " + integer);
                }
                return Observable.fromIterable(list).delay(10,TimeUnit.MILLISECONDS);
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, s);
            }
        });
  • zip(將兩個上游按照一定形式合并)同時可以結合切換線程(或者說指定線程)

       Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {           
    @Override                                                                                        
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {                     
        Log.d(TAG, "emit 1");                                                                        
        emitter.onNext(1);                                                                           
        Thread.sleep(1000);                                                                          

        Log.d(TAG, "emit 2");                                                                        
        emitter.onNext(2);                                                                           
        Thread.sleep(1000);                                                                          

        Log.d(TAG, "emit 3");                                                                        
        emitter.onNext(3);                                                                           
        Thread.sleep(1000);                                                                          

        Log.d(TAG, "emit 4");                                                                        
        emitter.onNext(4);                                                                           
        Thread.sleep(1000);                                                                          

        Log.d(TAG, "emit complete1");                                                                
        emitter.onComplete();                                                                        
    }                                                                                                
});                                                                                                  
Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {             
    @Override                                                                                        
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {                      
        Log.d(TAG, "emit A");                                                                        
        emitter.onNext("A");                                                                         
        Thread.sleep(1000);                                                                          
                                                                                 
        Log.d(TAG, "emit B");                                                                        
        emitter.onNext("B");                                                                         
        Thread.sleep(1000);                                                                          
                                                                                                     
        Log.d(TAG, "emit C");                                                                        
        emitter.onNext("C");                                                                         
        Thread.sleep(1000);                                                                          
                                                                                                     
        Log.d(TAG, "emit complete2");                                                                
        emitter.onComplete();                                                                        
    }                                                                                                
});                                                                                                  

Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {                 
    @Override                                                                                        
    public String apply(Integer integer, String s) throws Exception {                                
        return integer + s;                                                                          
    }                                                                                                
}).subscribe(new Observer<String>() {                                                                
    @Override                                                                                        
    public void onSubscribe(Disposable d) {                                                          
        Log.d(TAG, "onSubscribe");                                                                   
    }                                                                                                

    @Override                                                                                        
    public void onNext(String value) {                                                               
        Log.d(TAG, "onNext: " + value);                                                              
    }                                                                                                

    @Override                                                                                        
    public void onError(Throwable e) {                                                               
        Log.d(TAG, "onError");                                                                       
    }                                                                                                

    @Override                                                                                        
    public void onComplete() {                                                                       
        Log.d(TAG, "onComplete");                                                                    
    }                                                                                                
});

  • sample
    每隔指定的時間就從上游中取出一個事件發送給下游.但是這個方法有個缺點, 就是丟失了大部分的事件.
Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; ; i++) {
                    emitter.onNext(i);
                }
            }
        }).subscribeOn(Schedulers.io())
                .sample(2, TimeUnit.SECONDS)  //sample取樣
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "" + integer);
                    }
                });

  • interval操作符發送Long型的事件, 從0開始, 每隔指定的時間就把數字加1并發送出來
  • onBackpressureBuffer()
    onBackpressureDrop()
    onBackpressureLatest()
Flowable.interval(1, TimeUnit.MICROSECONDS).onBackpressureDrop()  
  • 零碎知識點
    • 上游可以發送無限個onNext, 下游也可以接收無限個onNext.
    • 當上游發送了一個onComplete后, 上游onComplete之后的事件將會繼續發送, 而下游收到onComplete事件之后將不再繼續接收事件.
    • 當上游發送了一個onError后, 上游onError之后的事件將繼續發送, 而下游收到onError事件之后將不再繼續接收事件.
    • 上游可以不發送onComplete或onError.
    • 最為關鍵的是onComplete和onError必須唯一并且互斥, 即不能發多個onComplete, 也不能發多個onError, 也不能先發一個onComplete, 然后再發一個onError, 反之亦然
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容

  • 我還沒能力寫好文章!但是堅持努力學習和提升自己!
    鄉村里放羊的貓閱讀 322評論 -1 1
  • banana課堂6 banana課堂(收到很多老師同學的鼓勵,真的很感動? ,愛你們~ 我會盡量改進的,介于時間有...
    banana課堂閱讀 326評論 0 1