前几天一直听几个朋友们说起RxJava多好用,无奈实在不知道那是个啥,干嘛用的。这几天公司闲下来了也抓紧恶补了一波,留点学习笔记也好自己回过头来看看。
跟AsyncTask / Handler差不多,RxJava也是做异步处理的,但是为什么放这AsyncTask / Handler不用来用这个呢,技术的更新换代必定有它的道理,学过之后就知道了。
先说一下原理吧
这里有两个对象 一个是Observable,另一个是Observer,顾名思义这两个一个是观察者一个是被观察者,他们两个通过Subscribe产生订阅关系。既当被观察者操作一些耗时操作,当结束时他会告诉观察者“我做完了”,并把他处理的结果交给观察者,然后观察者再决定把这些结果怎么处置,当然还需要我们手动指定观察者与被观察者的操作在哪个线程执行。
好,了解了原理我们再来看看怎么使用,我们就实现把drawable里面的图片显示在ui界面上吧
先导入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():基本的创造事件序列的方法。
just():将传入的参数依次发送出来。
from():将传入的数组拆分成具体对象后,依次发送出来。
Observable.create(newObservable.OnSubscribe() {//这里的Integer指的是创建好这个对象onNext往下传递的对象
@Override
public voidcall(Subscriber subscriber) {
for(int i:img){
try{
Thread.sleep(500); //这里延迟5ms是想 实现一个幻灯片效果
subscriber.onNext(i);//这里onNext方法会把里面携带的参数交给观察者来处理,这里是一个 int 值
}catch(InterruptedException e) {
e.printStackTrace();
}
}
subscriber.onCompleted();//一直给观察者传递消息,当停止传递消息时执行此方法
}
})
这里可以看到onNext传下去的是一个int值,但是我们的ui更新需要在主线程中进行,要是把提取图片之类的操作放在ui线程显然是不明智的,所以我们这里就需要一个map来进行转换
.map(new Func1() {
@Override
public Drawable call(Integer int) {//这个地方的int就是从被观察者那里通过onNext传下来的int值,而Drawable就是要继续往下传递的对象
Drawable drawable = getResources().getDrawable(int);
return drawable;//这里把取出来的Drawable继续往下传递
}
})
然后我们就需要来创建我们的观察者接收上面传过来的Drawable并且显示在ui界面上
new Observer() {
@Override
public void onCompleted() {//当接受结束时调用这个方法,前面说过
}
@Override
public void onError(Throwable e) {//当发生错误时调用这个方法
}
@Override
public void onNext(Drawable drawable) {//这里接收到的drawable就是上面传过来的
im.setImageDrawable(drawable);
}
现在我们已经创建好观察者、被观察者,并且把数据转换成了想要的形式,但是要通过什么方式才能使他们两个联系在一起呢,这里就用到了Subscribe
使用形式是这样的:
Observable.subscribe(Observable);
好,上完整代码
Observable.create(new Observable.OnSubscribe() {//这里的Integer指的是创建好这个对象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()//指定操作在哪个线程来执行
.observeOn(Schedulers.io())//指定操作在哪个线程来执行
.map(new Func1() {
@Override
public Drawable call(Integer ints) {
Drawable drawable = getResources().getDrawable(ints);
return drawable;
}
})
.observeOn(AndroidSchedulers.mainThread())//指定操作在哪个线程来执行
.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()//指定操作在哪个线程来执行
.observeOn(Schedulers.io())//指定操作在哪个线程来执行
上面咱也说过,他们的操作需要我们来指定在哪个线程来执行
subscribeOn(): 指定 subscribe() 所发生的线程,即 Observable.OnSubscribe 被激活时所处的线程。或者叫做事件产生的线程。换成人话就是说当被观察者执行onNext操作时执行线程,通常用在被观察者创建好的下一行代码。
observeOn(): 指定 Observer所运行在的线程。或者叫做事件消费的线程。就是观察者拿到了数据后我该执行的操作的线程。
好了到这里就能得到我们想要的结果了,但是这只是RxJava的九牛一毛,他的用法还有很多很多,这篇文章能教大家的不多希望能带你们入门。