在使用RxJava的第一步就是創建一個你所需要的Observable,根據不同的需求創建不同的Observable。
首先你得了解Observable的分類
Observable分類
-
Cold Observable
當沒有訂閱的時候,該Observable不處理任何事件,當有訂閱者發起訂閱后,才開始響應,從第一個數據開始發射。
-
Hot Observable
不管有沒有訂閱者,該Observable一直在發射數據。
關于‘冷’、‘熱’我是這樣理解的:‘冷’的Observable是默認定義了數據或者獲取數據的方式,每次訂閱后將所有的數據,按照一定的規則發射給你;‘熱’則是動態的數據,而這個被觀察者一直處于發射狀態,當你訂閱后,其實就是從現在開始接收到數據而已,這里的數據都是動態的、實時變化的,而不是定義Observable就把數據默認好了。
如何選擇合適的Observable
-
已經獲取到的數據進行處理 -
Cold
比較典型的例子,篩選一個數組中所有的偶數
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));
如果你單獨創建一個
Observable.fromArray(array)
這個被觀察者是沒有處理任何事件?
-
觸發一個固定事件獲取數據-
Cold
這種一般用于異步獲取數據,比如網絡請求:
//模擬一個耗時3秒的請求 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); //一般這種獲取數據方式的被觀察者,獲取到一個數據后就調用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()); });
結果
start#1493776191045 data#test end#1493776194051
這種方式創建的Observable也是
冷
的,可以在Demo去掉subscribe
訂閱,就會發現實際這個Observable什么事情都沒做。
-
創建一個當前狀態的Observable-
Hot
這種Observable實際運用中非常有用、方便、簡潔。比如對Activity的生命周期,可以做一個Observable,當生命周期改變時,對其發射數據。對TextView的text變化創建一個Observable,每當text變化的時候發射給訂閱者,等等。
這里已TextView text變化為例:
這里使用
BehaviorSubject
而不使用PublishSubject
是因為,在實際使用中我們需要從訂閱開始那一刻就知道目前TextView的text是什么,使用BehaviorSubject
會在訂閱那一刻將最后一次發射的數據發射給訂閱者,而PublishSubject
則是訂閱開始后,直到下次有text變化,那訂閱者才能接收到第一個數據。創建一個工具類
TextViews.java
public static Observable<CharSequence> textChange(final TextView textView){ //創建Observable,并對其設置默認值 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 當取消訂閱時候響應,同時取消監聽 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)); //點擊按鈕取消監聽 findViewById(R.id.cancel).setOnClickListener(v ->{ if(!disposable.isDisposed()){ disposable.dispose(); } });
在后續實際開發中基本只需要關心怎么使用
textChange
所返回的數據,而其變為Observable之后操作很多事件就變得很方便比如將其變為監聽text長度
TextViews.textChange(editText) .map(CharSequence::length) .subscribe(len-> Log.d("RxJava","text#"+len));
對于一個button,當Edittext的text長度大于4才能點擊
TextViews.textChange(editText) .map(CharSequence::length) .map(len->len>4) .subscribe(button::setEnabled);
總結
關于創建Observable的方式還有很多,這里簡單說了我自己最常用的部分。希望大家能給大家帶來一定的幫助。如果有錯誤的地方指出來,大家都共同學習下。
?