前幾天一直聽幾個朋友們說起RxJava多好用,無奈實在不知道那是個啥,干嘛用的。這幾天公司閑下來了也抓緊惡補了一波,留點學(xué)習(xí)筆記也好自己回過頭來看看。
跟AsyncTask / Handler差不多,RxJava也是做異步處理的,但是為什么放這AsyncTask / Handler不用來用這個呢,技術(shù)的更新?lián)Q代必定有它的道理,學(xué)過之后就知道了。
先說一下原理吧
這里有兩個對象 一個是Observable,另一個是Observer,顧名思義這兩個一個是觀察者一個是被觀察者,他們兩個通過Subscribe產(chǎn)生訂閱關(guān)系。既當(dāng)被觀察者操作一些耗時操作,當(dāng)結(jié)束時他會告訴觀察者“我做完了”,并把他處理的結(jié)果交給觀察者,然后觀察者再決定把這些結(jié)果怎么處置,當(dāng)然還需要我們手動指定觀察者與被觀察者的操作在哪個線程執(zhí)行。
好,了解了原理我們再來看看怎么使用,我們就實現(xiàn)把drawable里面的圖片顯示在ui界面上吧
先導(dǎo)入Rx包
compile'io.reactivex:rxjava:1.1.0'//Rx的包
compile'io.reactivex:rxandroid:1.1.0'//Rx的包
把我們要用的圖片拷貝在drawable目錄下并定義好imageview(不啰嗦);
Image Viewim;
int[] img={R.drawable.dog1,R.drawable.dog2,R.drawable.dog3,R.drawable.dog4};
先定義Observable,定義Observable的方法有好幾種,像create(),just(),from().
create():基本的創(chuàng)造事件序列的方法。
just():將傳入的參數(shù)依次發(fā)送出來。
from():將傳入的數(shù)組拆分成具體對象后,依次發(fā)送出來。
Observable.create(newObservable.OnSubscribe() {//這里的Integer指的是創(chuàng)建好這個對象onNext往下傳遞的對象
@Override
public voidcall(Subscriber subscriber) {
for(int i:img){
try{
Thread.sleep(500); //這里延遲5ms是想 實現(xiàn)一個幻燈片效果
subscriber.onNext(i);//這里onNext方法會把里面攜帶的參數(shù)交給觀察者來處理,這里是一個 int 值
}catch(InterruptedException e) {
e.printStackTrace();
}
}
subscriber.onCompleted();//一直給觀察者傳遞消息,當(dāng)停止傳遞消息時執(zhí)行此方法
}
})
這里可以看到onNext傳下去的是一個int值,但是我們的ui更新需要在主線程中進(jìn)行,要是把提取圖片之類的操作放在ui線程顯然是不明智的,所以我們這里就需要一個map來進(jìn)行轉(zhuǎn)換
.map(new Func1() {
@Override
public Drawable call(Integer int) {//這個地方的int就是從被觀察者那里通過onNext傳下來的int值,而Drawable就是要繼續(xù)往下傳遞的對象
Drawable drawable = getResources().getDrawable(int);
return drawable;//這里把取出來的Drawable繼續(xù)往下傳遞
}
})
然后我們就需要來創(chuàng)建我們的觀察者接收上面?zhèn)鬟^來的Drawable并且顯示在ui界面上
new Observer() {
@Override
public void onCompleted() {//當(dāng)接受結(jié)束時調(diào)用這個方法,前面說過
}
@Override
public void onError(Throwable e) {//當(dāng)發(fā)生錯誤時調(diào)用這個方法
}
@Override
public void onNext(Drawable drawable) {//這里接收到的drawable就是上面?zhèn)鬟^來的
im.setImageDrawable(drawable);
}
現(xiàn)在我們已經(jīng)創(chuàng)建好觀察者、被觀察者,并且把數(shù)據(jù)轉(zhuǎn)換成了想要的形式,但是要通過什么方式才能使他們兩個聯(lián)系在一起呢,這里就用到了Subscribe
使用形式是這樣的:
Observable.subscribe(Observable);
好,上完整代碼
Observable.create(new Observable.OnSubscribe() {//這里的Integer指的是創(chuàng)建好這個對象onNext往下傳遞的對象? ? ? ? ? ??
@Override? ? ? ? ? ?
?public void call(Subscribersubscriber) {
? ? ? ? ? ? ? ? for(int i:img){
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? Thread.sleep(500);
? ? ? ? ? ? ? ? ? ? ? ? subscriber.onNext(i);
? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {?
?? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }?
?? ? ? ? ? ? ? }?
?? ? ? ? ? ? ? subscriber.onCompleted();
? ? ? ? ? ? }?
?? ? ? }).subscribeOn(Schedulers.io()//指定操作在哪個線程來執(zhí)行
? ? ? ? .observeOn(Schedulers.io())//指定操作在哪個線程來執(zhí)行
? ? ? ? .map(new Func1() {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public Drawable call(Integer ints) {
? ? ? ? ? ? ? ? ? ? ? ? Drawable drawable = getResources().getDrawable(ints);
? ? ? ? ? ? ? ? ? ? ? ? return drawable;
? ? ? ? ? ? ? ? ? ? }
?? ? ? })?
? ? ? ? ? ? ? .observeOn(AndroidSchedulers.mainThread())//指定操作在哪個線程來執(zhí)行
? ? ? ? ? ? ? ? .subscribe(new Observer() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Drawable drawable) {
im.setImageDrawable(drawable);
}
});
怎么突然冒出個這個:
.subscribeOn(Schedulers.io()//指定操作在哪個線程來執(zhí)行
.observeOn(Schedulers.io())//指定操作在哪個線程來執(zhí)行
上面咱也說過,他們的操作需要我們來指定在哪個線程來執(zhí)行
subscribeOn(): 指定 subscribe() 所發(fā)生的線程,即 Observable.OnSubscribe 被激活時所處的線程。或者叫做事件產(chǎn)生的線程。換成人話就是說當(dāng)被觀察者執(zhí)行onNext操作時執(zhí)行線程,通常用在被觀察者創(chuàng)建好的下一行代碼。
observeOn(): 指定 Observer所運行在的線程?;蛘呓凶鍪录M的線程。就是觀察者拿到了數(shù)據(jù)后我該執(zhí)行的操作的線程。
好了到這里就能得到我們想要的結(jié)果了,但是這只是RxJava的九牛一毛,他的用法還有很多很多,這篇文章能教大家的不多希望能帶你們?nèi)腴T。
