淺談Rxjava(二)

上一篇中講了Rxjava的基本使用,這篇來講一下Rxjava的一些高級操作

一.Rxjava中的變換

RxJava 提供了對事件序列進(jìn)行變換的支持,這是它的核心功能之一,也是大多數(shù)人說 “RxJava 真是太好用了” 的最大原因。所謂變換,就是將事件序列中的對象或整個(gè)序列進(jìn)行加工處理,轉(zhuǎn)換成不同的事件或事件序列。
首先看一個(gè) map() 的例子:

Observable.just("images/logo.png") // 輸入類型 String
    .map(new Func1<String, Bitmap>() {
        @Override
        public Bitmap call(String filePath) { // 參數(shù)類型 String
            return getBitmapFromPath(filePath); // 返回類型 Bitmap
        }
    })
    .subscribe(new Action1<Bitmap>() {
        @Override
        public void call(Bitmap bitmap) { // 參數(shù)類型 Bitmap
            showBitmap(bitmap);
        }
    });

可以看到,map() 方法將參數(shù)中的 String 對象轉(zhuǎn)換成一個(gè) Bitmap 對象后返回,而在經(jīng)過 map() 方法后,事件的參數(shù)類型也由 String 轉(zhuǎn)為了 Bitmap。這種直接變換對象并返回的,是最常見的也最容易理解的變換。不過 RxJava 的變換遠(yuǎn)不止這樣,它不僅可以針對事件對象,還可以針對整個(gè)事件隊(duì)列,這使得 RxJava 變得非常靈活。

再看一個(gè) flatMap() 的例子:

String[] filePaths = ...;
Subscriber<Bitmap> subscriber = new Subscriber<Bitmap>() {
    @Override
    public void onNext(Bitmap bitmap) {
        ...
    }
    ...
};
Observable.from(filePaths)
    .flatMap(new Func1<String, Observable<Bitmap>>() {
        @Override
        public Observable<Bitmap> call(String filePath) {
            return Observable.from(getAllPhoto(filePath));
        }
    })
    .subscribe(subscriber);

從上面的代碼可以看出, flatMap() 和 map() 有一個(gè)相同點(diǎn):它也是把傳入的參數(shù)轉(zhuǎn)化之后返回另一個(gè)對象。但需要注意,和 map() 不同的是, flatMap() 中返回的是個(gè) Observable 對象,并且這個(gè) Observable 對象并不是被直接發(fā)送到了 Subscriber 的回調(diào)方法中。
flatMap() 的原理是這樣的:1. 使用傳入的事件對象創(chuàng)建一個(gè) Observable 對象;2. 并不發(fā)送這個(gè) Observable, 而是將它激活,于是它開始發(fā)送事件;3. 每一個(gè)創(chuàng)建出來的 Observable 發(fā)送的事件,都被匯入同一個(gè) Observable ,而這個(gè) Observable 負(fù)責(zé)將這些事件統(tǒng)一交給 Subscriber 的回調(diào)方法。這三個(gè)步驟,把事件拆成了兩級,通過一組新創(chuàng)建的 Observable 將初始的對象『鋪平』之后通過統(tǒng)一路徑分發(fā)了下去。而這個(gè)『鋪平』就是 flatMap() 所謂的 flat

二.Rxjava中的Subject

關(guān)于Subject,官方文檔的解釋是這樣的:Subject可以看成是一個(gè)橋梁或者代理,在某些ReactiveX實(shí)現(xiàn)中(如RxJava),它同時(shí)充當(dāng)了Observer和Observable的角色。因?yàn)樗且粋€(gè)Observer,它可以訂閱一個(gè)或多個(gè)Observable;又因?yàn)樗且粋€(gè)Observable,它可以轉(zhuǎn)發(fā)它收到(Observe)的數(shù)據(jù),也可以發(fā)射新的數(shù)據(jù)。從官方解釋中,我提取出三個(gè)要點(diǎn):

它可以充當(dāng)Observable;
它可以充當(dāng)Observer;
它是Observable和Observer之間的橋梁;

Subject的分類解析

  • ** AsyncSubject**
    Observer會(huì)接收AsyncSubject的onComplete()之前的最后一個(gè)數(shù)據(jù),如果因異常而終止,AsyncSubject將不會(huì)釋放任何數(shù)據(jù),但是會(huì)向Observer傳遞一個(gè)異常通知。

  • ** BehaviorSubject**
    Observer會(huì)接收到BehaviorSubject被訂閱之前的最后一個(gè)數(shù)據(jù),再接收其他發(fā)射過來的數(shù)據(jù),如果BehaviorSubject被訂閱之前沒有發(fā)送任何數(shù)據(jù),則會(huì)發(fā)送一個(gè)默認(rèn)數(shù)據(jù)。

  • ** PublishSubject**
    PublishSubject比較容易理解,相對比其他Subject常用,它的Observer只會(huì)接收到PublishSubject被訂閱之后發(fā)送的數(shù)據(jù)。

  • ** ReplaySubject**
    ReplaySubject會(huì)發(fā)射所有數(shù)據(jù)給觀察者,無論它們是何時(shí)訂閱的。也有其它版本的ReplaySubject,在重放緩存增長到一定大小的時(shí)候或過了一段時(shí)間后會(huì)丟棄舊的數(shù)據(jù)。

接下來用代碼說明它如何充當(dāng)Observable,Observer以及Observable和Observer之間的橋梁:

創(chuàng)建Observable并發(fā)射數(shù)據(jù):

PublishSubject<String> publishSubject = PublishSubject.create();
publishSubject.onNext("as Observable");
publishSubject.onCompleted();```
創(chuàng)建Observer訂閱Observable并接收數(shù)據(jù):

publishSubject.subscribe(new Observer<String>() {
@Override
public void onCompleted() {

      }

      @Override
      public void onError(Throwable e) {

      }

      @Override
      public void onNext(String s) {

      }
  });```

借用Subject來連接Observable和Observer:

PublishSubject<String> publishSubject = PublishSubject.create();
   Observable.create(new Observable.OnSubscribe<String>() {
          @Override
          public void call(Subscriber<? super String> subscriber) {

              subscriber.onNext("as Bridge");
              subscriber.onCompleted();
          }
      }).subscribe(publishSubject);

      publishSubject.subscribe(new Observer<String>() {
          @Override
          public void onCompleted() {

          }

          @Override
          public void onError(Throwable e) {

          }

          @Override
          public void onNext(String s) {
              ...
          }
      });```

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,388評論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內(nèi)容