前言
终究没有经受住RxJava的诱惑,只恨自己来的比较晚,走起~
RxJava 是什么?
一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库~
Rx Java 有什么优势?
逻辑简洁
异步
RxJava 能做什么?
EventBus事件中心
与Retrofit结合进行网络处理
RxBinding
….
结实RxJava
一、代码分析
我们先来看一下这坨代码:
new Thread() {
@Override
public void run() {
super.run();
for (File folder : folders) {
File[] files = folder.listFiles();
for (File file : files) {
if (file.getName().endsWith(".png")) {
final Bitmap bitmap = getBitmapFromFile(file);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
imageCollectorView.addImage(bitmap);
}
});
}
}
}
}}.start();
上面就是一个图片的遍历、过滤、加载过程,可是有强迫症的程序员都会很难过,因为又看到了影响心情的代码。
用RxJava如何实现呢?
Observable.from(folders)
.flatMap(new Func1>() {
@Override
public Observable call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".png");
}
})
.map(new Func1() {
@Override
public Bitmap call(File file) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});
吾皇勿怒,臣妾知道代码并没有减少,可是臣妾说的是逻辑简单,链式结构非常清晰不是吗?
相信您在顿悟了5s中之后也看到了其好处~
二、基本概念
1、扩展的观察者模式
RxJava 的异步实现,是通过一种扩展的观察者模式来实现的,A 对象(观察者)对 B 对象(被观察者)的某种变化高度敏感,需要在 B 变化的一瞬间做出反应。
2、RxJava的四个基本概念:
Observable (可观察者,即被观察者)
Observer (观察者)
subscribe (订阅)
事件 : onNext()、onCompleted() 和 onError()
Observable类(被观察者)
Observable是被观察者,它可以在需要的时候发出事件通知Observer(观察者),它决定什么时候触发事件以及怎样触发。
Observable对象创建是通过Observable.create()方法进行创建的。
通过Observable.OnSubscribe中的call()方法定义事件的触发规则,call()的参数中有一个Subscriber对象,这个对象会被存储到返回的Observable对象中,当Obserable被订阅的时候,call()方法会自动被调用。上面的示例代码中就是一次调用onNext()方法和onCompleted()方法。
当然这个示例代码中事件是确定的,就是打印一串字符,在实际运用中事件是不确定的,可能是任何事件。但是我们都可以通过这种订阅的方式实现观察者模式。
Observer类(观察者)
Observer即为观察者,Observer决定了事件触发时有怎么样的行为,具体的实现方式就在上面的代码中。
Observer是一个接口,通过它我们可以创建观察者对象,同时在RxJava中也提供了一个实现类Subscriber,Subscriber是一个抽象类,它是对Observer的实现和扩展。
Subscriber和Observer的区别
a、Subscriber在Observer的基础上新增加了onStart()方法,该方法的执行是在subscribe刚开始,事件还没被发送的时候调用,通常可以在其中做一些初始化的操作,但是有一点需要注意的是该方法执行的线程是subscribe发生的线程,并不能指定线程,所以这点需要特别注意。要想指定线程做准备工作可以选择doOnSubscribe()方法。
b、unsubscribed()方法,该方法是Subscriber实现了另一个接口Subscription的一个方法,该方法的作用是取消订阅,该方法执行后,Subscriber将不再接收事件。同时还有一个isUnSubscribed()方法,顾名思义该方法是判断当前订阅是否被取消,所以在调用unsubscribed()方法前可以先通过isUnSubscibed()进行判断。
之所以说该方法重要是因为,Observable调用subscribe()方法之后会持有Observer或Subscriber的引用,如果不及时释放掉,很可能会引起内存的泄露,所以unsubscribed()方法执行最好在onPause(),onStop(),onDestroy()方法中。
在基本功能上Observer和Subscriber是基本一致的,要知道在RxJava中,Observer也总是被转换成Suberscriber后才被使用的。
subscribe订阅
创建完Observable被观察者和Observer观察者后需要通过subscribe将两者关联起来,这样整个驱动链就建立起来了。
那subscribe()方法是如何工作的呢?
下面分析RxJava的subscribe()部分源码
public final Subscription subscribe(final Observer super T> observer) {
if (observer instanceof Subscriber) {
return subscribe((Subscriber super T>)observer);
}
if (observer == null) {
throw new NullPointerException("observer is null");
}
return subscribe(new ObserverSubscriber(observer));
}
在代码中可以看出subscribe()方法中调用了subscribe((Subscriber
public final Subscription subscribe(Subscriber super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
其中又调用了subscribe(subscriber,this)方法。
下面来看看subscribe(subscriber,this)方法具体做了什么事。
static Subscription subscribe(Subscriber super T> subscriber, Observable observable) { if (subscriber == null) { throw new IllegalArgumentException("subscriber can not be null"); } if (observable.onSubscribe == null) { throw new IllegalStateException("onSubscribe function can not be null."); } subscriber.onStart(); if (!(subscriber instanceof SafeSubscriber)) { subscriber = new SafeSubscriber(subscriber); } try { RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber); return RxJavaHooks.onObservableReturn(subscriber); } catch (Throwable e) { Exceptions.throwIfFatal(e); if (subscriber.isUnsubscribed()) { RxJavaHooks.onError(RxJavaHooks.onObservableError(e)); } else { try { subscriber.onError(RxJavaHooks.onObservableError(e)); } catch (Throwable e2) { Exceptions.throwIfFatal(e2); RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2); RxJavaHooks.onObservableError(r); throw r; // NOPMD } } return Subscriptions.unsubscribed(); } }
发现其中主要调用了两个方法,onStart()方法和call()方法。
所以observable.subscribe(observer)方法可以简化成
public Subscription subscribe(Subscriber subscriber) {
subscriber.onStart();
onSubscribe.call(subscriber);
return subscriber;
}
从代码可以看出,订阅事件主要做如下几件事:
onstart 准备操作
call 业务逻辑处理,而且业务逻辑处理并不是Observable创建时运行的,call()方法执行的时候开始运行的~
事件
onNext(): 普通事件,每个事件执行之后的event。
onCompleted(): 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的onNext() 发出时,需要触发 onCompleted() 方法作为标志。 onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。
注意 :
在一个正确运行的事件序列中, onCompleted() 和 onError() 有且只有一个,并且是事件序列中的最后一个。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在队列中调用了其中一个,就不应该再调用另一个。
结语
此篇博文是RxJava最基本的介绍了,相信大家对RxJava有了初步的认识,接下来会对RXJava进行更加深层次的分析与使用介绍~