RxJava學習一:初識
引入依賴:
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參考:MovieGuide、RxVolley、CaMnter / EasyGank、一個用於學習RxJava操作符的APP
Rxjava在android開發中越來越火,觀看各位大神的介紹,自己加以學習和整理。剛接觸時就被其強大的功能吸引住了;錯過了就要再等一萬年了
啪啪啪啪啪!!
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;
相關文章
- 大話RxJava:一、初識RxJava與基本運用RxJava
- Redis學習(一)——初識RedisRedis
- JMS學習(一):初識JMS
- Redis學習筆記(一)——初識RedisRedis筆記
- RxJava2 學習(一)RxJava
- RxJava 學習筆記 -- 基礎知識RxJava筆記
- Vue 學習筆記 (一) -- 初識 VueCli 3Vue筆記
- Git學習1:初識GitGit
- webpack學習(二)初識打包配置Web
- 【Nginx學習筆記】-初識NginxNginx筆記
- JVM學習筆記——初識JVMJVM筆記
- Hibernate學習:初識hibernate
- Struts2學習筆記(一)初識Strut2筆記
- Java開發學習(一)----初識Spring及其核心概念JavaSpring
- iOS逆向學習筆記 - 彙編(一) - 初識彙編iOS筆記
- 跟我一起學習C++ 之 初識C++C++
- RxJava 學習筆記RxJava筆記
- LevelDB學習筆記 (1):初識LevelDB筆記
- nginx學習(二):初識配置檔案Nginx
- Android RxJava:這是一份RxJava使用入門學習指南AndroidRxJava
- 玩轉RxJava2.x 學習教程(一)RxJava
- Laravel 學習--資料庫使用初識 1Laravel資料庫
- Java學習筆記--資料庫初識Java筆記資料庫
- 初識C語言(01)—學習筆記C語言筆記
- RxJava2 學習(二)RxJava
- Android開發之從零開始學RxJava 2.x(一)認識RxjavaAndroidRxJava
- 給初學者的RxJava2.0教程(一)RxJava
- 【強化學習篇】--強化學習從初識到應用強化學習
- 跟我一起學習C++ 之 初識名稱空間C++
- vtk學習記錄(三)——初識vtkRenderer
- Python教程學習:初識Python-01Python
- python綜合學習七之TensorFlow初識Python
- JavaScript 學習初篇(第一課)JavaScript
- 初識 webpack (一)Web
- RocketMq(一)初識MQ
- 初識Django(一)Django
- 一.初識JavaJava
- mysql初識(一)MySql