在使用RxJava的第一步就是創(chuàng)建一個(gè)你所需要的Observable转唉,根據(jù)不同的需求創(chuàng)建不同的Observable。
首先你得了解Observable的分類
Observable分類
-
Cold Observable
當(dāng)沒有訂閱的時(shí)候,該Observable不處理任何事件火的,當(dāng)有訂閱者發(fā)起訂閱后壶愤,才開始響應(yīng),從第一個(gè)數(shù)據(jù)開始發(fā)射馏鹤。
-
Hot Observable
不管有沒有訂閱者公你,該Observable一直在發(fā)射數(shù)據(jù)。
關(guān)于‘冷’假瞬、‘熱’我是這樣理解的:‘冷’的Observable是默認(rèn)定義了數(shù)據(jù)或者獲取數(shù)據(jù)的方式,每次訂閱后將所有的數(shù)據(jù)迂尝,按照一定的規(guī)則發(fā)射給你脱茉;‘熱’則是動(dòng)態(tài)的數(shù)據(jù),而這個(gè)被觀察者一直處于發(fā)射狀態(tài)垄开,當(dāng)你訂閱后琴许,其實(shí)就是從現(xiàn)在開始接收到數(shù)據(jù)而已,這里的數(shù)據(jù)都是動(dòng)態(tài)的溉躲、實(shí)時(shí)變化的榜田,而不是定義Observable就把數(shù)據(jù)默認(rèn)好了。
如何選擇合適的Observable
-
已經(jīng)獲取到的數(shù)據(jù)進(jìn)行處理 -
Cold
比較典型的例子锻梳,篩選一個(gè)數(shù)組中所有的偶數(shù)
Integer[] array = new Integer[]{1,2,3,4,5,6,7,8}; Observable.fromArray(array) .filter(item -> item%2 == 0) .subscribe(item -> System.out.println("item#"+item));
如果你單獨(dú)創(chuàng)建一個(gè)
Observable.fromArray(array)
這個(gè)被觀察者是沒有處理任何事件?
-
觸發(fā)一個(gè)固定事件獲取數(shù)據(jù)-
Cold
這種一般用于異步獲取數(shù)據(jù)箭券,比如網(wǎng)絡(luò)請(qǐng)求:
//模擬一個(gè)耗時(shí)3秒的請(qǐng)求 String getData(){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return "test"; } Observable.create((ObservableOnSubscribe<String>) e -> { try { System.out.println("start#"+System.currentTimeMillis()); String data = getData(); e.onNext(data); //一般這種獲取數(shù)據(jù)方式的被觀察者,獲取到一個(gè)數(shù)據(jù)后就調(diào)用onComplete e.onComplete(); }catch (Exception e1){ e.onError(e1); } }).observeOn(Schedulers.newThread()) .subscribe(data->{ System.out.println("data#"+data); System.out.println("end#"+System.currentTimeMillis()); });
結(jié)果
start#1493776191045 data#test end#1493776194051
這種方式創(chuàng)建的Observable也是
冷
的疑枯,可以在Demo去掉subscribe
訂閱辩块,就會(huì)發(fā)現(xiàn)實(shí)際這個(gè)Observable什么事情都沒做。
-
創(chuàng)建一個(gè)當(dāng)前狀態(tài)的Observable-
Hot
這種Observable實(shí)際運(yùn)用中非常有用荆永、方便废亭、簡(jiǎn)潔。比如對(duì)Activity的生命周期具钥,可以做一個(gè)Observable豆村,當(dāng)生命周期改變時(shí),對(duì)其發(fā)射數(shù)據(jù)骂删。對(duì)TextView的text變化創(chuàng)建一個(gè)Observable掌动,每當(dāng)text變化的時(shí)候發(fā)射給訂閱者,等等桃漾。
這里已TextView text變化為例:
這里使用
BehaviorSubject
而不使用PublishSubject
是因?yàn)榛捣耍趯?shí)際使用中我們需要從訂閱開始那一刻就知道目前TextView的text是什么,使用BehaviorSubject
會(huì)在訂閱那一刻將最后一次發(fā)射的數(shù)據(jù)發(fā)射給訂閱者撬统,而PublishSubject
則是訂閱開始后适滓,直到下次有text變化,那訂閱者才能接收到第一個(gè)數(shù)據(jù)恋追。創(chuàng)建一個(gè)工具類
TextViews.java
public static Observable<CharSequence> textChange(final TextView textView){ //創(chuàng)建Observable凭迹,并對(duì)其設(shè)置默認(rèn)值 BehaviorSubject<CharSequence> observable = BehaviorSubject.createDefault(textView.getText()); TextWatcher textWatcher = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable s) { observable.onNext(s); Log.d("RxJava","onChange"); } }; textView.addTextChangedListener(textWatcher); //doOnDispose 當(dāng)取消訂閱時(shí)候響應(yīng)罚屋,同時(shí)取消監(jiān)聽 return observable.doOnDispose(()->{ textView.removeTextChangedListener(textWatcher); observable.onComplete(); }); }
使用
EditText editText = (EditText) findViewById(R.id.edit); final Disposable disposable = TextViews.textChange(editText) .subscribe(text-> Log.d("RxJava","text#"+text)); //點(diǎn)擊按鈕取消監(jiān)聽 findViewById(R.id.cancel).setOnClickListener(v ->{ if(!disposable.isDisposed()){ disposable.dispose(); } });
在后續(xù)實(shí)際開發(fā)中基本只需要關(guān)心怎么使用
textChange
所返回的數(shù)據(jù),而其變?yōu)镺bservable之后操作很多事件就變得很方便比如將其變?yōu)楸O(jiān)聽text長(zhǎng)度
TextViews.textChange(editText) .map(CharSequence::length) .subscribe(len-> Log.d("RxJava","text#"+len));
對(duì)于一個(gè)button嗅绸,當(dāng)Edittext的text長(zhǎng)度大于4才能點(diǎn)擊
TextViews.textChange(editText) .map(CharSequence::length) .map(len->len>4) .subscribe(button::setEnabled);
總結(jié)
關(guān)于創(chuàng)建Observable的方式還有很多脾猛,這里簡(jiǎn)單說了我自己最常用的部分。希望大家能給大家?guī)硪欢ǖ膸椭沭H绻绣e(cuò)誤的地方指出來猛拴,大家都共同學(xué)習(xí)下。
?