初识RxJava2

257 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

1. RxJava是一个实现异步操作的库,相比于AsyncTask和Handler,RxJava可以在复杂的代码面前保持清晰的逻辑。
2. RxJava的异步实现,是通过一种扩展的观察者模式来实现的。
3. github地址 github.com/ReactiveX/R…

RxAndroid

1. RxAndroid是RxJava在Android平台的扩展,包含了一些能够简化Android开发的工具,比如一些调度器。
2. github地址 github.com/ReactiveX/R…

RxJava的基本使用

1. 创建Observer(观察者)

观察者决定了触发事件的时候有怎样的行为。

Observer observer = new Observer<String>() {
    public void onSubscribe(Disposable d) {
        Log.i(TAG, "onSubscribe");
    }
    public void onNext(String s) {
        Log.i(TAG, "onNext   "+s);
    }
    public void onError(Throwable t) {
        Log.i(TAG, "onError");
    }
    public void onComplete() {
        Log.i(TAG, "onComplete");
    }
};
  • Disposable Disposable是在RxJava 2 中新增的方法,可以做到切断的操作,让观察者不再接收被观察者的事件。
  • onNext 发送普通事件。将要处理的事件添加到队列中。
  • onError 事件队列异常。在处理事件的时候,如果发生异常,将触发onError方法,此时队列将自动终止,不在有事件发出。
  • onComplete 事件队列完结。当不再有新的onNext发出时,需要触发onComplete方法作为标志。

2. 创建被观察者

被观察着决定了什么时候触发什么样的事件

Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
        Log.i(TAG, "发送onNext --  张三");
        emitter.onNext("张三");
        Log.i(TAG, "发送onNext --  李四");
        emitter.onNext("李四");
        Log.i(TAG, "发送onNext --  王五");
        emitter.onNext("王五");
        Log.i(TAG, "发送onError");
        emitter.onError(null);
        Log.i(TAG, "发送第一个onComplete");
        emitter.onComplete();
        Log.i(TAG, "发送第二个onComplete");
        emitter.onComplete();
        Log.i(TAG, "onNext --  赵六");
        emitter.onNext("赵六");
    }
});
  • ObservableEmitter ObservableEmitter是事件发射器,可以发射next事件、complete事件和error事件。
  • 被观察者发送一个onComplete事件之后,任然可以继续发送事件,但是当观察者接收到了onComplete事件之后,将不再接收任何事件。
  • 被观察者发送一个onError事件之后,仍然可以继续发送之后的其他事件,但是当观察者接收到了onError事件之后,将不再接收任何事件。
  • onError事件是唯一的,如果发送两个onError事件,在接收到第二个的时候,程序将可能崩溃。
  • onCompleteonError是互斥的,即执行了其中一个,另一个将不再执行。

3. 订阅

observable.subscribe(observer);

4. 执行结果

01-23 14:57:18.996 9947-9947/com.xp.note.rxjava I/MainActivity: onSubscribe
01-23 14:57:18.997 9947-9947/com.xp.note.rxjava I/MainActivity: 发送onNext --  张三
01-23 14:57:19.000 9947-9947/com.xp.note.rxjava I/MainActivity: onNext   张三
01-23 14:57:19.000 9947-9947/com.xp.note.rxjava I/MainActivity: 发送onNext --  李四
01-23 14:57:19.000 9947-9947/com.xp.note.rxjava I/MainActivity: onNext   李四
01-23 14:57:19.000 9947-9947/com.xp.note.rxjava I/MainActivity: 发送onNext --  王五
01-23 14:57:19.001 9947-9947/com.xp.note.rxjava I/MainActivity: onNext   王五
01-23 14:57:19.001 9947-9947/com.xp.note.rxjava I/MainActivity: 发送onError
01-23 14:57:19.002 9947-9947/com.xp.note.rxjava I/MainActivity: onError
01-23 14:57:19.003 9947-9947/com.xp.note.rxjava I/MainActivity: 发送第一个onComplete
01-23 14:57:19.003 9947-9947/com.xp.note.rxjava I/MainActivity: 发送第二个onComplete
01-23 14:57:19.007 9947-9947/com.xp.note.rxjava I/MainActivity: onNext --  赵六

由于观察者收到了一次onError,所以之后无论被观察者发出什么样的事件都将不再接收。

public abstract class Subject<T> extends Observable<T> implements Observer<T> 根据Subject类的定义可以看出Subject既是Observer,同时也是Observable,所以他可以充当Observer,也可以充当Observable,而且他也是链接ObserverObservable的桥梁,Subject一共有四种。

Subject的使用

1. AsyncSubject

Observer只会收到AsyncSubject发射的在onComplete之前的最后一个数据。简单的说使用AsyncSubject无论发射多少数据,Observer永远都只能收到一个。但是当程序出错而终止时。AsyncSubject不会发射任何数据,只会传递一个异常通知。

AsyncSubject<String> asyncSubject = AsyncSubject.create();
asyncSubject.onNext("张三");
asyncSubject.onNext("李四");
try {
    int a = 1/0;
}catch (Exception e){
    asyncSubject.onError(e);
}
asyncSubject.onNext("王五");
asyncSubject.onComplete();
asyncSubject.subscribe(new Observer<String>() {
    public void onSubscribe(Disposable d) {
        Log.i(TAG, "onSubscribe");
    }
    public void onNext(String s) {
        Log.i(TAG, "onNext: "+s);
    }
    public void onError(Throwable e) {
        Log.i(TAG, "onError");
    }
    public void onComplete() {
        Log.i(TAG, "onComplete ");
    }
});

执行结果为

01-24 14:22:12.462 11437-11437/com.xp.note.rxjava I/MainActivity: onSubscribe
01-24 14:22:12.462 11437-11437/com.xp.note.rxjava I/MainActivity: onError

2. BehaviorSubject

Observer订阅BehaviorSubject的时候,BehaviorSubject将发送离订阅最近的上一个值。如果没有该值,则发送一个默认值,然后继续发送后面的其他数据。如果程序遇到错误,BehaviorSubject将不会发送任何数据,而是传递一个异常通知。

BehaviorSubject behaviorSubject = BehaviorSubject.createDefault("默认值");
// 此处订阅将受到 默认值,张三,李四,王五
behaviorSubject.onNext("张三");
// 此处订阅将受到 张三,李四,王五
behaviorSubject.onNext("李四");	
// 此处订阅将受到 李四,王五
behaviorSubject.onNext("王五");
// 此处订阅将受到 王五
behaviorSubject.subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.i(TAG, "accept: "+s);
    }
});
behaviorSubject.onComplete();
// 此处订阅将受到没有回调

3. PublishSubject

PublishSubjet只会发送订阅时间之后的数据;即从哪里订阅,就从哪里开始发送。所以在订阅之前的数据就会丢失。

PublishSubject publishSubject = PublishSubject.create();
//此处订阅将收到 张三,李四,王五
publishSubject.onNext("张三");
//此处订阅将收到 李四,王五
publishSubject.onNext("李四");
//此处订阅将收到 王五
publishSubject.subscribe(observer);
publishSubject.onNext("王五");
publishSubject.onComplete();
//此处订阅将没有回调

4. ReplaySubject

无论何时订阅ReplaySubjectReplaySubject都将会把所有的历史信息全部发出。

ReplaySubject replaySubject = ReplaySubject.create();
replaySubject.onNext("张三");
replaySubject.onNext("李四");
replaySubject.subscribe(observer);
replaySubject.onNext("王五");
replaySubject.onComplete();

结果输出为

01-24 15:06:25.638 13955-13955/com.xp.note.rxjava I/MainActivity: onSubscribe
01-24 15:06:25.638 13955-13955/com.xp.note.rxjava I/MainActivity: onNext: 张三
01-24 15:06:25.638 13955-13955/com.xp.note.rxjava I/MainActivity: onNext: 李四
01-24 15:06:25.638 13955-13955/com.xp.note.rxjava I/MainActivity: onNext: 王五
01-24 15:06:25.638 13955-13955/com.xp.note.rxjava I/MainActivity: onComplete