RxJava初見

核心思想

  • 觀察者模式
  1. RxJava最核心的兩個東西是Observables(被觀察者韵洋,事件源)和Subscribers(觀察者)。Observables發(fā)出一系列事件芬探,Subscribers處理這些事件。
  2. 一個Observable可以發(fā)出零個或者多個事件,直到結束或者出錯盒粮。每發(fā)出一個事件,就會調用它的Subscriber的onNext方法奠滑,最后調用Subscriber.onNext()或者Subscriber.onError()結束丹皱。
  3. 如果一個Observerble沒有任何的的Subscriber妒穴,那么這個Observable是不會發(fā)出任何事件的。
  • 異步

  • 鏈式調用

基本使用

創(chuàng)建與訂閱

  • 創(chuàng)建觀察者(事件處理)和被觀察者(事件源)
  • 訂閱
// 創(chuàng)建被觀察者
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("Hello, world!");
        subscriber.onCompleted();
    }
});

// 創(chuàng)建觀察者
Subscriber<String> subscriber = new Subscriber<String>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(String s) {
        System.out.println(s);
        showMsg(s);
    }
};

// 訂閱事件
observable.subscribe(subscriber);

簡潔模式:

Observable<String> observable1 = Observable.just("你好摊崭!");
Action1<String> onNextAction = new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
};

observable1.subscribe(onNextAction);

變換

map()

它將一種數(shù)據(jù)類型變換為另一種數(shù)據(jù)類型
同數(shù)據(jù)類型:

// 同數(shù)據(jù)類型
Observable.just("Hello, world!")
.map(new Func1<String, String>() {
    @Override
    public String call(String s) {
        return s + " -fengmlo";
    }
})
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
});

不同數(shù)據(jù)類型:

// 不同數(shù)據(jù)類型
Observable.just("你好讼油!")
.map(new Func1<String, Integer>() {
    @Override
    public Integer call(String s) {
        return s.hashCode();
    }
})
.subscribe(new Action1<Integer>() {
    @Override
    public void call(Integer integer) {
        System.out.println(integer);
        showMsg(integer + "");
    }
});

多次變換:

// 多次變換
Observable.just("你好!")
.map(new Func1<String, Integer>() {
    @Override
    public Integer call(String s) {
        return s.hashCode();
    }
})
.map(new Func1<Integer, String>() {
    @Override
    public String call(Integer integer) {
        return Integer.toString(integer);
    }
})
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
}); 

集合操作

from()

它接收一個集合作為輸入呢簸,然后每次輸出一個元素給subscriber

//集合操作
Observable.from(new String[]{"url1", "url2", "url3"})//它接收一個集合作為輸入矮台,然后每次輸出一個元素給subscriber
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
});

flatMap()

它接收一個Observable的輸出作為輸入,同時輸出另外一個Observable

query("Hello, world!")
.flatMap(new Func1<List<String>, Observable<String>>() {//flatMap()接收一個Observable的輸出作為輸入阔墩,同時輸出另外一個Observable嘿架。
    @Override
    public Observable<String> call(List<String> strings) {
        return Observable.from(strings);
    }
})
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
});

現(xiàn)在假設有這么個函數(shù):

Observable<List<String>> query(String text) {
    List<String> list = Arrays.asList(new String[]{"url1", "url2", "url3"});
    return Observable.just(list);
}

flatMap把一個Observable變成一堆Observable

query("Hello, world!")
.flatMap(new Func1<List<String>, Observable<String>>() {//flatMap()接收一個Observable的輸出作為輸入,同時輸出另外一個Observable啸箫。
    @Override
    public Observable<String> call(List<String> strings) {
        return Observable.from(strings);
    }
})
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
});

flatMap把一個Observable變成一個Observable耸彪,可以用map替換

query("Hello, world!")
.flatMap(new Func1<List<String>, Observable<String>>() {//flatMap()接收一個Observable的輸出作為輸入,同時輸出另外一個Observable忘苛。
    @Override
    public Observable<String> call(List<String> strings) {
        return Observable.from(strings);
    }
})
.flatMap(new Func1<String, Observable<String>>() {
    @Override
    public Observable<String> call(String s) {
        return Observable.just(s+s);
    }
})
/* 與前一個flatMap功能一致
.map(new Func1<String, String>() {
    @Override
    public String call(String s) {
        return s+s;
    }
})
*/
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        System.out.println(s);
        showMsg(s);
    }
});

filter()

輸出和輸入相同的元素蝉娜,并且會過濾掉那些不滿足檢查條件的

query("數(shù)據(jù)過濾")
.flatMap(new Func1<List<String>, Observable<String>>() {
    @Override
    public Observable<String> call(List<String> strings) {
        return Observable.from(strings);
    }
})
.filter(new Func1<String, Boolean>() {
    @Override
    public Boolean call(String s) {
        return !s.equals("url1");
    }
}) //filter()輸出和輸入相同的元素,并且會過濾掉那些不滿足檢查條件的扎唾。
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        showMsg(s);
    }
});

指定結果個數(shù)

query("數(shù)據(jù)過濾")
.flatMap(new Func1<List<String>, Observable<String>>() {
    @Override
    public Observable<String> call(List<String> strings) {
        return Observable.from(strings);
    }
})
.take(2) //take()輸出最多指定數(shù)量的結果召川。
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        showMsg(s);
    }
});

訂閱前對數(shù)據(jù)操作

//訂閱之前對數(shù)據(jù)進行操作
query("數(shù)據(jù)過濾")
.flatMap(new Func1<List<String>, Observable<String>>() {
    @Override
    public Observable<String> call(List<String> strings) {
        return Observable.from(strings);
    }
})
.take(2) //take()輸出最多指定數(shù)量的結果。
.doOnNext(new Action1<String>() {
    @Override
    public void call(String s) {
        // TODO: 2016/8/15 something
    }
}) //doOnNext()允許我們在每次輸出一個元素之前做一些額外的事情
.subscribe(new Action1<String>() {
    @Override
    public void call(String s) {
        showMsg(s);
    }
});

調度器

異步是RxJava最重要的特性之一胸遇,RxJava使用subscribeOn()observeOn()來分別指定訂閱的線程和觀察的線程荧呐,訂閱的線程即獲取、處理數(shù)據(jù)的線程纸镊,觀察的線程則一般是對數(shù)據(jù)進行展示的線程
eg:

retrofitService.getImage(url)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(bitmap -> myImageView.setImageBitmap(bitmap));

RxAndroid

AndroidSchedulers

retrofitService.getImage(url)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(bitmap -> myImageView.setImageBitmap(bitmap));

AndroidObservable

AndroidObservable倍阐,它提供了跟多的功能來配合Android的生命周期。bindActivity()和bindFragment()方法默認使用AndroidSchedulers.mainThread()來執(zhí)行觀察者代碼逗威,這兩個方法會在Activity或者Fragment結束的時候通知被觀察者停止發(fā)出新的消息峰搪。

AndroidObservable.bindActivity(this, retrofitService.getImage(url)) 
    .subscribeOn(Schedulers.io())
    .subscribe(bitmap -> myImageView.setImageBitmap(bitmap);

AndroidObservable.fromBroadcast()方法允許你創(chuàng)建一個類似BroadcastReceiver的Observable對象。下面的例子展示了如何在網(wǎng)絡變化的時候被通知到:

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
AndroidObservable.fromBroadcast(context, filter)
    .subscribe(intent -> handleConnectivityChange(intent));

ViewObservable

ViewObservable可以給View添加了一些綁定凯旭。如果你想在每次點擊view的時候都收到一個事件概耻,可以使用ViewObservable.clicks(),或者你想監(jiān)聽TextView的內容變化罐呼,可以使用ViewObservable.text()

ViewObservable.clicks(mCardNameEditText, false)
    .subscribe(view -> handleClick(view));

參考鏈接

深入淺出RxJava(一:基礎篇)
深入淺出RxJava(二:操作符)
深入淺出RxJava三--響應式的好處
深入淺出RxJava四-在Android中使用響應式編程

給 Android 開發(fā)者的 RxJava 詳解

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鞠柄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子弄贿,更是在濱河造成了極大的恐慌春锋,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,835評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件差凹,死亡現(xiàn)場離奇詭異期奔,居然都是意外死亡侧馅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評論 2 383
  • 文/潘曉璐 我一進店門呐萌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馁痴,“玉大人,你說我怎么就攤上這事肺孤÷拊危” “怎么了?”我有些...
    開封第一講書人閱讀 156,481評論 0 345
  • 文/不壞的土叔 我叫張陵赠堵,是天一觀的道長小渊。 經(jīng)常有香客問我,道長茫叭,這世上最難降的妖魔是什么酬屉? 我笑而不...
    開封第一講書人閱讀 56,303評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮揍愁,結果婚禮上呐萨,老公的妹妹穿的比我還像新娘。我一直安慰自己莽囤,他們只是感情好谬擦,可當我...
    茶點故事閱讀 65,375評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朽缎,像睡著了一般惨远。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上话肖,一...
    開封第一講書人閱讀 49,729評論 1 289
  • 那天锨络,我揣著相機與錄音,去河邊找鬼狼牺。 笑死,一個胖子當著我的面吹牛礼患,可吹牛的內容都是我干的是钥。 我是一名探鬼主播,決...
    沈念sama閱讀 38,877評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼缅叠,長吁一口氣:“原來是場噩夢啊……” “哼悄泥!你這毒婦竟也來了?” 一聲冷哼從身側響起肤粱,我...
    開封第一講書人閱讀 37,633評論 0 266
  • 序言:老撾萬榮一對情侶失蹤弹囚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后领曼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸥鹉,經(jīng)...
    沈念sama閱讀 44,088評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蛮穿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,443評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了毁渗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片践磅。...
    茶點故事閱讀 38,563評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖灸异,靈堂內的尸體忽然破棺而出府适,到底是詐尸還是另有隱情,我是刑警寧澤肺樟,帶...
    沈念sama閱讀 34,251評論 4 328
  • 正文 年R本政府宣布檐春,位于F島的核電站,受9級特大地震影響么伯,放射性物質發(fā)生泄漏疟暖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,827評論 3 312
  • 文/蒙蒙 一蹦狂、第九天 我趴在偏房一處隱蔽的房頂上張望誓篱。 院中可真熱鬧,春花似錦凯楔、人聲如沸窜骄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邻遏。三九已至,卻和暖如春虐骑,著一層夾襖步出監(jiān)牢的瞬間准验,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評論 1 264
  • 我被黑心中介騙來泰國打工廷没, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留糊饱,地道東北人。 一個月前我還...
    沈念sama閱讀 46,240評論 2 360
  • 正文 我出身青樓颠黎,卻偏偏與公主長得像另锋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狭归,可洞房花燭夜當晚...
    茶點故事閱讀 43,435評論 2 348

推薦閱讀更多精彩內容