RxJava學習一:初識

weixin_33751566發表於2016-04-10

首先介紹Github地址:RxJavaRxAndroid

引入依賴:

compile 'io.reactivex:rxjava:x.y.z'

compile 'io.reactivex:rxandroid:x.y.z'

(版本號是文章釋出時的最新穩定版)

部分內容參考:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/

順便提幾個demo參考:MovieGuideRxVolleyCaMnter / EasyGank一個用於學習RxJava操作符的APP

Rxjava在android開發中越來越火,觀看各位大神的介紹,自己加以學習和整理。剛接觸時就被其強大的功能吸引住了;錯過了就要再等一萬年了

啪啪啪啪啪!!

1882392-d75698b7da630d98.gif

github官方文件介紹“a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(譯:在 Java VM 上使用可觀測的序列來組成非同步的、基於事件的程式的庫);激情的發現這不是我們日常開發中所需要處理的棘手問題嗎!

RxJava核心零部件為Observables(被觀察者,事件源)和Subscribers(觀察者)。Observables發出一系列事件,Subscribers處理這些事件。而所謂的事件可以理解為你所需要處理的事件,比如:click、event等等。此時你可以結合設計模式中的觀察者模式,但是有一點不同,那就是如果一個Observerble沒有任何的的Subscriber,那麼這個Observable是不會發出任何事件的,而且rxjava更為強大之處在於“非同步”,簡潔、低調而奢華。

一個 Observable 可以有多個 Subscribers,並且通過 Observable 發出的每一個 item,該 item 將會被髮送到 Subscriber.onNext() 方法來進行處理。一旦 Observable 不再發出 items,它將會呼叫 Subscriber.onCompleted() 方法,或如果有一個出錯的話 Observable 會呼叫 Subscriber.onError() 方法。

現在,我們知道了很多關於 Observable 和 Subscriber 類,我們可以繼續去介紹有關 Observables 的建立和訂閱。


Observable> stringObservable = Observable.create(new Observable.OnSubscribe() {

@Override

public void call(Subscriber subscriber) {

subscriber.onNext(listDatas.get(0));

subscriber.onNext(listDatas.get(1));

subscriber.onNext(listDatas.get(2));//連續發出三組資料

subscriber.onCompleted();

}

});

建立一個 Subscriber,響應這些發出的資料流。

Subscriber stringSubscriber = new Subscriber() {

@Override

public void onCompleted() {

System.out.println("Complete!");

}

@Override

public void onError(Throwable e) {

}

@Override

public void onNext(List value) {

System.out.println("onNext: " + value);

}

};

stringObservable.subscribe(stringSubscriber);//最後呼叫此方法建立連線


我們的 Subscriber 只是簡單的把任何發出的 items 列印出來,完成之後通知我們。一旦你有一個 Observable 和一個 Subscriber,可以通過 Observable.subscribe() 方法將他們聯絡起來。

上面所有這些程式碼可以簡單的通過使用 Observable.just() 方法來建立一個 Observable 去發出這些定義的值,並且我們的 Subscriber 可以改變成匿名的內部類,如下:


Observable.just(getListData()).subscribe(new Subscriber() {  @Override  public void onCompleted() {  System.out.println("Complete!");  }  @Override  public void onError(Throwable e) {}  @Override  public void onNext(Integer value) {  System.out.println("onNext: " + value);  }});  //onNext()方法被呼叫,被髮送的資料列表會作為引數傳入;既然不再有資料可以傳送(我們在Observable.just()中只讓Observable傳送一個資料),onComplete()方法會被呼叫。


在這個例子中我們不關心Observable何時完成資料的傳輸,所以我們不用在onComplete()方法裡寫程式碼。而且在這裡不會有異常丟擲,所以我們也不用管onError()方法。

操作符:

感謝大聖:程式亦非猿的《RxJava操作符學習筆記》

通過create()、just( )、from( )繫結(輸入)事件來構造物件;備註:Observable.from()方法,它接收一個集合作為輸入,然後每次輸出一個元素給subscriber;

通過map( )、filter( )將輸入的事件進行過濾成我們希望獲取的事件,返回結果給觀察者響應;

通過Observable.flatMap()接收一個Observable的輸出作為輸入,同時輸出另外一個Observable。

Take()指定最多輸出量;doOnNext()允許我們在每次輸出一個元素之前做一些額外的事情;

lift()對目標訂閱者進行層層包裝,通過Observable.Operator,讓包裝後的訂閱者可以直接處理的事件。

compose()是對多個lift()的封裝;

throttleFirst()在每次事件觸發後的一定時間間隔內丟棄新的事件,用作防抖什麼的,按一次後,多少時間內再按了也沒用。

onStart()這是Subscriber增加的方法。它會在subscribe剛開始,而事件還未傳送之前被呼叫,可以用於做一些準備工作,例如資料的清零或重置。這是一個可選方法,預設情況下它的實現為空。需要注意的是,如果對準備工作的執行緒有要求(例如彈出一個顯示進度的對話方塊,這必須在主執行緒執行),onStart()就不適用了,因為它總是在subscribe所發生的執行緒被呼叫,而不能指定執行緒。要在指定的執行緒來做準備工作,可以使用doOnSubscribe()方法,具體可以在後面的文中看到。

unSubscribe()這是Subscriber所實現的另一個介面Subscription的方法,用於取消訂閱。在這個方法被呼叫後,Subscriber將不再接收事件。一般在這個方法呼叫前,可以使用isUnsubscribed()先判斷一下狀態。unsubscribe()這個方法很重要,因為在subscribe()之後,Observable會持有Subscriber的引用,這個引用如果不能及時被釋放,將有記憶體洩露的風險。所以最好保持一個原則:要在不再使用的時候儘快在合適的地方(例如onPause()onStop()等方法中)呼叫unsubscribe()來解除引用關係,以避免記憶體洩露的發生。

重點:執行緒控制與非同步操作

首先介紹一下:Scheduler:執行緒控制


Observable.just(1, 2, 3, 4) // IO 執行緒,由 subscribeOn() 指定

.subscribeOn(Schedulers.io())

.observeOn(Schedulers.newThread())

.map(mapOperator) // 新執行緒,由 observeOn() 指定

.observeOn(Schedulers.io())

.map(mapOperator2) // IO 執行緒,由 observeOn() 指定

.observeOn(AndroidSchedulers.mainThread)

.subscribe(subscriber);  // Android 主執行緒,由 observeOn() 指定

·Schedulers.immediate():直接在當前執行緒執行,相當於不指定執行緒。這是預設的Scheduler。

·Schedulers.newThread():總是啟用新執行緒,並在新執行緒執行操作。


·Schedulers.io(): I/O操作(讀寫檔案、讀寫資料庫、網路資訊互動等)所使用的Scheduler。行為模式和newThread()差不多,區別在於io()的內部實現是是用一個無數量上限的執行緒池,可以重用空閒的執行緒,因此多數情況下io()比newThread()更有效率。不要把計算工作放在io()中,可以避免建立不必要的執行緒。

·Schedulers.computation():計算所使用的Scheduler。這個計算指的是CPU密集型計算,即不會被I/O等操作限制效能的操作,例如圖形的計算。這個Scheduler使用的固定的執行緒池,大小為CPU核數。不要把I/O操作放在computation()中,否則I/O操作的等待時間會浪費CPU。

·另外,Android還有一個專用的AndroidSchedulers.mainThread(),它指定的操作將在Android主執行緒執行。

有了這幾個Scheduler,就可以使用subscribeOn()和observeOn()兩個方法來對執行緒進行控制了。

·subscribeOn():指定subscribe()所發生的執行緒,即Observable.OnSubscribe被啟用時所處的執行緒。或者叫做事件產生的執行緒。

·observeOn():指定Subscriber所執行在的執行緒。或者叫做事件消費的執行緒。

在 Android開發中有一個常見的場景是需要在後臺執行緒去分擔一定量的工作,一旦該任務完成,會將結果回撥到主執行緒去顯示結果。

在 Android中,我們有多種方法來做這樣的事:用 AsyncTasks, Services 等。

而在rxjava中如何完美解決的呢?


Observable operationObservable = Observable.create(newObservable.OnSubscribe() {

@Override

public void call(Subscribersubscriber) {

subscriber.onNext(doLongOperation());

subscriber.onCompleted();

}

})

.subscribeOn(Schedulers.io())// subscribeOn the I/O thread

.observeOn(AndroidSchedulers.mainThread()); // observeOn the UI Thread

//建立了 Observable將會呼叫 doLongOperation() 方法,將返回的結果作為引數給 onNext() 方法。

public String doLongOperation() {

try {

Thread.sleep(1000);

} catch (InterruptedException e){

}

return "isComplete!";

}


新增了一個新的 button,被點選時,我們需要給我們的 Observable 做訂閱。


rxOperationButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(final View v){

v.setEnabled(false);

operationObservable.subscribe(newSubscriber() {

@Override

public void onCompleted() {

v.setEnabled(true);

}

@Override

public void onError(Throwable e) {}

@Override

public void onNext(String value) {

Toast.makeText(this, value, Toast.LENGTH_LONG).show();

}

});

}

});


對於任何 Observable你可以定義在兩個不同的執行緒,Observable 會操作在它上面。使用 Observable.observeOn()可以定義在一個執行緒上,可以用來監聽和檢查從 Observable 最新發出的 items (Subscriber 的onNext,onCompleted 和 onError 方法會執行在 observeOn 所指定的執行緒上),並使用Observable.subscribeOn() 來定義一個執行緒,將其執行我們 Observable 的程式碼(長時間執行的操作)。

RxJava預設情況下是單執行緒的,你會需要利用 observeOn()和 subscribeOn() 方法為你的應用帶來多執行緒操作。RxJava 附帶了幾個現成的 Schedulers 給 Observables 使用,如:Schedulers.io() (用於 I/O 操作),Schedulers.computation()(計算工作),和Schedulers.newThread()(為任務建立的新執行緒)。然而,從 Android 的角度來看,你可能想知道如何把訂閱程式碼執行到主執行緒。我們可以用 RxAndroid 庫來實現這一目標。

我們修改 Observable將用 Schedulers.io() 去訂閱,並用AndroidSchedulers.mainThread() 方法將觀察的結果返回到 UI 執行緒上。現在,當我們點選按鈕,我們可以看到當操作執行時它將不再阻塞 UI 執行緒。

如果你一直在關注程式碼,你可能會注意到你呼叫的Observable.subscribe()的返回值是一個 Subscription 物件。Subscription 類只有兩個方法,unsubscribe() 和 isUnsubscribed()。為了防止可能的記憶體洩露,在你的 Activity 或 Fragment 的 onDestroy 裡,用 Subscription.isUnsubscribed() 檢查你的Subscription 是否是 unsubscribed。如果呼叫了 Subscription.unsubscribe() ,Unsubscribing將會對 items 停止通知給你的 Subscriber,並允許垃圾回收機制釋放物件,防止任何 RxJava 造成記憶體洩露。如果你正在處理多個 Observables 和 Subscribers,所有的 Subscription 物件可以新增到 CompositeSubscription,然後可以使用CompositeSubscription.unsubscribe() 方法在同一時間進行退訂(unsubscribed)。

後續:繼續深入學習執行緒操作。自己留著看看就可以了,方便自己記錄學習Ok!!

參考:《給 Android開發者的 RxJava詳解》  http://blog.csdn.net/meegomeego/article/details/49155989

《RxJava入門》http://www.open-open.com/lib/view/open1447245102194.html

相關文章