RxJava的牛逼在哪里诸蚕?
1:提供了對事件序列進(jìn)行變換的支持
所謂變換踪宠,就是將事件序列中的對象或整個序列進(jìn)行加工處理,轉(zhuǎn)換成不同的事件或事件序列
2:實(shí)現(xiàn)了對線程的自由控制
通過Scheduler進(jìn)行對call()中發(fā)射數(shù)據(jù)的線程控制,subscribeOn(Schedulers.io()) 這個線程的核心底層是基于線程池來完成妈嘹,一定要清楚多線程與rxjava結(jié)合應(yīng)用
在不指定線程的情況下柳琢, RxJava 遵循的是線程不變的原則,即:在哪個線程調(diào)用 subscribe()润脸,就在哪個線程生產(chǎn)事件柬脸;在哪個線程生產(chǎn)事件,就在哪個線程消費(fèi)事件毙驯。如果需要切換線程倒堕,就需要用到 Scheduler (調(diào)度器)。
Scheduler調(diào)度器的api
在RxJava 中爆价,Scheduler ——調(diào)度器垦巴,相當(dāng)于線程控制器媳搪,RxJava 通過它來指定每一段代碼應(yīng)該運(yùn)行在什么樣的線程。RxJava 已經(jīng)內(nèi)置了幾個 Scheduler 骤宣,它們已經(jīng)適合大多數(shù)的使用場景:
Schedulers.immediate():
直接在當(dāng)前線程運(yùn)行秦爆,相當(dāng)于不指定線程。這是默認(rèn)的 Scheduler憔披。Schedulers.newThread():
總是啟用新線程等限,并在新線程執(zhí)行操作。Schedulers.io():
I/O 操作(讀寫文件芬膝、讀寫數(shù)據(jù)庫望门、網(wǎng)絡(luò)信息交互等)所使用的 Scheduler。行為模式和 newThread() 差不多锰霜,區(qū)別在于 io() 的內(nèi)部實(shí)現(xiàn)是是用一個無數(shù)量上限的線程池筹误,可以重用空閑的線程,因此多數(shù)情況下 io() 比 newThread() 更有效率锈遥。不要把計算工作放在 io() 中纫事,可以避免創(chuàng)建不必要的線程。Schedulers.computation()
計算所使用的 Scheduler所灸。這個計算指的是 CPU 密集型計算丽惶,即不會被 I/O 等操作限制性能的操作,例如圖形的計算爬立。這個 Scheduler 使用的固定的線程池钾唬,大小為 CPU 核數(shù)。不要把 I/O 操作放在 computation() 中侠驯,否則 I/O 操作的等待時間會浪費(fèi) CPU抡秆。
另外, Android 還有一個專用的 AndroidSchedulers.mainThread()吟策,它指定的操作將在 Android 主線程運(yùn)行儒士。
有了這幾個 Scheduler ,就可以使用 subscribeOn() 和 observeOn() 兩個方法來對線程進(jìn)行控制了檩坚。
subscribeOn(): 指定 subscribe() 所發(fā)生的線程着撩,即Observable.OnSubscribe 被激活時所處的線程∝椅或者叫做事件產(chǎn)生的線程拖叙。
observeOn(): 指定 Subscriber 所運(yùn)行在的線程÷咐郑或者叫做事件消費(fèi)的線程薯鳍。
資料收集
- 基礎(chǔ)之rxjava觀察者模式
http://blog.csdn.net/caihongdao123/article/details/51878760 - 線程調(diào)度Scheduler機(jī)制
http://blog.csdn.net/xmxkf/article/details/51821940
http://blog.csdn.net/caihongdao123/article/details/51897793 - 基礎(chǔ)模式
http://www.reibang.com/nb/5002005 - 官方中文文檔
https://mcxiaoke.gitbooks.io/rxdocs/content/operators/Map.html - 給 Android 開發(fā)者的 RxJava 詳解(很火的一篇入門文章)
http://gank.io/post/560e15be2dca930e00da1083
http://blog.csdn.net/angcyo/article/details/50345705(基礎(chǔ))
Rxjava是什么
Rx其實(shí)就是一個使用可觀察數(shù)據(jù)流進(jìn)行異步編程的編程接口,結(jié)合了觀察者模式挨措、迭代器模式和函數(shù)式編程的精華挖滤。說白了就是針對一個數(shù)據(jù)流有著一套嚴(yán)格規(guī)范以及一套很牛逼的實(shí)現(xiàn)方式的一個庫崩溪。
Rx = Observables(數(shù)據(jù)源) + LINQ(各種操作) + Schedulers(調(diào)度器)
我們用個思維導(dǎo)圖來分辨一下:
只看概念有點(diǎn)懵逼,是不是壶辜,沒關(guān)系悯舟!下面來實(shí)例詳細(xì)說明
Observable.from(folders)
.flatMap(new Func1<File, Observable<File>>() {
@Override
public Observable<File> call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1<File, Boolean>() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".png");
}
})
.map(new Func1<File, Bitmap>() {
@Override
public Bitmap call(File file) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())//上面的call()發(fā)生在IO線程里
.observeOn(AndroidSchedulers.mainThread())//回調(diào)發(fā)生在主線程里
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});
加載圖片將會發(fā)生在 IO 線程,而設(shè)置圖片則被設(shè)定在了主線程砸民。這就意味著抵怎,即使加載圖片耗費(fèi)了幾十甚至幾百毫秒的時間,也不會造成絲毫界面的卡頓岭参。
我們根據(jù)上面的思維導(dǎo)圖再來剖析一下這個例子:
看到這里應(yīng)該對Rx有個基本的了解了反惕!
Rxjava的核心原則觀察者模式
沒錯核心就是觀察者模式!在Rxjava的觀察者模式當(dāng)然也是演侯,Observable
(被觀察者)姿染、 Observer (觀察者),那么觀察者秒际,被觀察者也有了悬赏,還差一個溝通的橋梁那么 subscribe(訂閱)就來了,來實(shí)現(xiàn)訂閱關(guān)系娄徊。
來個實(shí)例
Observable.just("android","java","c")
.observeOn(Schedulers.io())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
//這里當(dāng)onNext()執(zhí)行三遍后才會最終執(zhí)行到這里
}
@Override
public void onError(Throwable e) {
//onCompleted(),onError()是互斥事件
}
@Override
public void onNext(String s) {
Logger.e("======"+s);//會依次打印出
}
})
上面的實(shí)例中看到怎么沒有看到Observer (觀察者)闽颇,其實(shí)Subscriber就是Observer 的抽象類。下面看一下這三個方法
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("Hello");
subscriber.onNext("Hi");
subscriber.onNext("Aloha");
subscriber.onCompleted();
}
});
String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);}
Observable observable = Observable.just("Hello", "Hi", "Aloha");
上面三個方法其實(shí)都是一樣的寄锐,只不過下面兩個會依次調(diào)用
// 將會依次調(diào)用:
onNext("Hello");
onNext("Hi");
onNext("Aloha");
onCompleted();
下面來了解下Rxjava常見的操作處理分類