1、事件监听注册与反注册
- BehaviorSubject
- PublishSubject
- AsyncSubject
- ReplaySubject
- SerializedSubject
- CompositeDisposable
1.1 Subject
- 都继承Subject,既是Observable,也是Observer
- 一般作为Observable使用,可以注册多个Observer,就像我们以前注册多个listener一样
1.1.1 AsyncSubject
- 一个AsyncSubject只在原始Observable完成后,发射来自原始Observable的最后一个值。(如果原始Observable没有发射任何值,AsyncObject也不发射任何值)它会把这最后一个值发射给任何后续的观察者。
- 然而,如果原始的Observable因为发生了错误而终止,AsyncSubject将不会发射任何数据,只是简单的向前传递这个错误通知。
1.1.2 BehaviorSubject
- BehaviorSubject每次注册会发射注册之前最近发射的一个事件和注册之后的事件(比如系统广播,监听网络变化,只要设置监听,就会发送一条网络变化的广播等等)
- 然而,如果原始的Observable因为发生了一个错误而终止,BehaviorSubject将不会发射任何数据,只是简单的向前传递这个错误通知。
// observer will receive all 4 events (including "default"). BehaviorSubject<Object> subject = BehaviorSubject.createDefault("default"); subject.subscribe(observer); subject.onNext("one"); subject.onNext("two"); subject.onNext("three"); // observer will receive the "one", "two" and "three" events, but not "zero" BehaviorSubject<Object> subject = BehaviorSubject.create(); subject.onNext("zero"); subject.onNext("one"); subject.subscribe(observer); subject.onNext("two"); subject.onNext("three"); // observer will receive only onComplete BehaviorSubject<Object> subject = BehaviorSubject.create(); subject.onNext("zero"); subject.onNext("one"); subject.onComplete(); subject.subscribe(observer); // observer will receive only onError BehaviorSubject<Object> subject = BehaviorSubject.create(); subject.onNext("zero"); subject.onNext("one"); subject.onError(new RuntimeException("error")); subject.subscribe(observer); } </pre> *
1.1.3 PublishSubject
- PublishSubject只发射注册之后发射的事件(不关心之前发射的数据)
- 如果原始的Observable因为发生了一个错误而终止,PublishSubject将不会发射任何数据,只是简单的向前传递这个错误通知。
PublishSubject<Object> subject = PublishSubject.create(); // observer1 will receive all onNext and onComplete events subject.subscribe(observer1); subject.onNext("one"); subject.onNext("two"); // observer2 will only receive "three" and onComplete subject.subscribe(observer2); subject.onNext("three"); subject.onComplete();
1.1.4 ReplaySubject
- ReplaySubject会发射所有来自原始Observable的数据给观察者,无论它们是何时订阅的。也有其它版本的ReplaySubject,在重放缓存增长到一定大小的时候或过了一段时间后会丢弃旧的数据(原始Observable发射的)。
缓存2条数据: ReplaySubject subject = ReplaySubject.createWithSize(2); subject.onNext(0); subject.onNext(1); subject.onNext(3); subject.onNext(4); subject.onNext(5); subject.subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "accept: " + integer); } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) { } }, new Action() { @Override public void run() throws Exception { Log.d(TAG, "run: onComplete"); } }); subject.onNext(6); subject.onNext(7); subject.onComplete();
输出结果:
accept: 4
accept: 5
accept: 6
accept: 7
run: onComplete
1.1.5 SerializedSubject
- 如果你把
Subject
当作一个 Observable使用,注意不要从多个线程中调用它的onNext方法(包括其它的on系列方法),这可能导致同时(非顺序)调用,这会违反Observable协议,给Subject的结果增加了不确定性。 -
串行化:要避免此类问题,你可以将
Subject
转换为一个SerializedSubject
,直接调用Subject的toSerialized接口:
public final Subject<T> toSerialized() { if (this instanceof SerializedSubject) { return this; } return new SerializedSubject<T>(this); }
1.2 CompositeDisposable
- rxjava虽然好用,但是总所周知,容易遭层内存泄漏。也就说在订阅了事件后没有及时取阅,导致在activity或者fragment销毁后仍然占用着内存,无法释放。而disposable便是这个订阅事件,可以用来取消订阅。但是在什么时候取消订阅呢?可以使用CompositeDisposable
- 定义:一个disposable的容器,可以容纳多个disposable,添加和去除的复杂度为O(1)。
/** * A disposable container that can hold onto multiple other disposables and * offers O(1) add and removal complexity. */
- 如果这个CompositeDisposable容器已经是处于dispose的状态,那么所有加进来的disposable都会被自动切断。所以说可以创建一个
BaseActivity
,用CompositeDisposable来管理订阅事件disposable,然后在acivity销毁的时候,调用compositeDisposable.dispose()
就可以切断所有订阅事件,防止内存泄漏。 - 源码
1.3 项目
2、单事件监听
- Completable
- Single
- Maybe
2.1 定义
- 在Rxjava2中,Observale和Flowable都是用来发射数据流的,但是,我们在实际应用中,很多时候,需要发射的数据并不是数据流的形式,而只是一条单一的数据,或者一条完成通知,或者一条错误通知。在这种情况下,我们再使用Observable或者Flowable就显得有点大材小用,于是,为了满足这种单一数据或通知的使用场景,便出现了Observable的简化版——Single、Completable、Maybe。
- 只发射一条单一的数据,或者一条异常通知,不能发射完成通知,其中数据与通知只能发射一个。
- 项目
* Example:
* <pre><code>
* Disposable d = Single.just("Hello World")
* .delay(10, TimeUnit.SECONDS, Schedulers.io())
* .subscribeWith(new DisposableSingleObserver<String>() {
* @Override
* public void onStart() {
* System.out.println("Started");
* }
*
* @Override
* public void onSuccess(String value) {
* System.out.println("Success: " + value);
* }
*
* @Override
* public void onError(Throwable error) {
* error.printStackTrace();
* }
* });
*
* Thread.sleep(5000);
*
* d.dispose();
* </code></pre>
2.3 Completable
- 只发射一条完成通知,或者一条异常通知,不能发射数据,其中完成通知与异常通知只能发射一个
- 项目
* Example:
* <pre><code>
* Disposable d = Completable.complete()
* .delay(10, TimeUnit.SECONDS, Schedulers.io())
* .subscribeWith(new DisposableCompletableObserver() {
* @Override
* public void onStart() {
* System.out.println("Started");
* }
*
* @Override
* public void onError(Throwable error) {
* error.printStackTrace();
* }
*
* @Override
* public void onComplete() {
* System.out.println("Done!");
* }
* });
*
* Thread.sleep(5000);
*
* d.dispose();
* </code></pre>
2.4 Maybe
- 可发射一条单一的数据,以及发射一条完成通知,或者一条异常通知,其中完成通知和异常通知只能发射一个,发射数据只能在发射完成通知或者异常通知之前,否则发射数据无效。
* Example: * <pre><code> * Disposable d = Maybe.just("Hello World") * .delay(10, TimeUnit.SECONDS, Schedulers.io()) * .subscribeWith(new DisposableMaybeObserver<String>() { * @Override * public void onStart() { * System.out.println("Started"); * } * * @Override * public void onSuccess(String value) { * System.out.println("Success: " + value); * } * * @Override * public void onError(Throwable error) { * error.printStackTrace(); * } * * @Override * public void onComplete() { * System.out.println("Done!"); * } * }); * * Thread.sleep(5000); * * d.dispose(); * </code></pre>
3、EventBus用RxJava实现(即广播)
- 定义
public final class RxBus { private final Subject mBus; public static RxBus getInstance() { return Holder.INSTANCE; } private RxBus() { mBus = PublishSubject.create().toSerialized(); } public <U> Observable<U> register(final Class<U> clazz) { return mBus.ofType(clazz); } public void post(Object o) { mBus.onNext(o); } public void unregister(Disposable d) { if (d != null && !d.isDisposed()) { d.dispose(); } } private static final class Holder { private static final RxBus INSTANCE = new RxBus(); } }
- 注册
Disposable disposable1 = RxBus.getInstance().register(ChapterOne.class) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<ChapterOne>() { @Override public void accept(ChapterOne chapterOne) throws Exception { Log.d(TAG, "receive event ChapterOne"); } }); mDisposable1 = disposable1;
- 发送事件
RxBus.getInstance().post(new ChapterOne());
- 反注册
@Override protected void onDestroy() { super.onDestroy(); RxBus.getInstance().unregister(mDisposable1); }