一篇博客让你了解RxJava

RxJava可以说是2016年最流行的项目之一了,最近也接触了一下RxJava,于是想写一篇博客,希望能通过这篇博客让大家能对其进行了解,本篇博客是基于RxJava2.0,跟RxJava1.0还是有很多不同的

基础知识

RxJava的核心就是“异步”两个字,其最关键的东西就是两个:

  1. Observable(被观察者)

  2. Observer/Subscriber(观察者)

Observable可以发出一系列的 事件,这里的事件可以是任何东西,例如网络请求、复杂计算处理、数据库操作、文件操作等等,事件执行结束后交给 Observer回调处理。

Observable可以理解为事件的发送者,就好像快递的寄出者,而这些事件就好比快递
Observer可以理解为事件的接收者,就好像快递的接收者

那他们之间是如何进行联系的呢?答案就是通过subscribe()方法,下面的代码就是RXJAVA中Observable与Observer进行关联的典型方式:

//创建一个被观察者 Observable
    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(5);
            e.onNext(6);
            e.onNext(7);
            e.onNext(8);
            e.onComplete();
        }
    });

    //创建观察者observer
    Observer<Integer> observer = new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.d(TAG, "subscribe");
        }

        @Override
        public void onNext(Integer value) {
            Log.d(TAG, value.toString());
        }

        @Override
        public void onError(Throwable e) {
            Log.d(TAG, "error");
        }

        @Override
        public void onComplete() {
            Log.d(TAG, "complete");
        }
    };
    //建立关联
    observable.subscribe(observer);

运行项目,我们可以看到,数字已经打印出来
这里写图片描述

这里需要强调的是: 只有当观察者和被观察者建立连接之后, 被观察者才会开始发送事件. 也就是调用了subscribe()方法之后才开始发送事件.

上面我们看到观察者和被观察者的逻辑是分开写的,那能不能合在一起写呢?答案是肯定的,这也是RxJava比较突出的优点,那就是链式操作,代码如下:

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(5);
        e.onNext(6);
        e.onNext(7);
        e.onNext(8);
        e.onComplete();
    }
}).subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "subscribe");
    }

    @Override
    public void onNext(Integer value) {
        Log.d(TAG, value.toString());
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "error");
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "complete");
    }
});

有时候,你可能觉得,我就打印几个数,还要把Observable写的那么麻烦,能不能简便一点呢?答案是肯定的,RxJava内置了很多简化创建Observable对象的函数,比如Observable.just就是用来创建只发出一个事件就结束的Observable对象,上面创建Observable对象的代码可以简化为一行

Observable<String> observable = Observable.just("hello");

同样对于Observer,这个例子中,我们其实并不关心OnComplete和OnError,我们只需要在onNext的时候做一些处理,这时候就可以使用Consumer类。

Observable<String> observable = Observable.just("hello");
   Consumer<String> consumer = new Consumer<String>() {
       @Override
       public void accept(String s) throws Exception {
           System.out.println(s);
       }
   };
    observable.subscribe(consumer);

这里写图片描述

其实在RxJava中,我们可以为 Observer中的三种状态根据自身需要分别创建一个回调动作,通过Action 来替代onComplete():,通过Consumer来替代 onError(Throwable t)和onNext(T t)

Observable<String> observable = Observable.just("hello");
    Action onCompleteAction = new Action() {
        @Override
        public void run() throws Exception {
            Log.i(TAG, "complete");
        }
    };
    Consumer<String> onNextConsumer = new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.i(TAG, s);
        }
    };
    Consumer<Throwable> onErrorConsumer = new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception {
            Log.i(TAG, "error");
        }
    };
    observable.subscribe(onNextConsumer, onErrorConsumer, onCompleteAction);

}

这里写图片描述

Observable.just同样可以发送多个参数

Observable observable = Observable.just("you", "are", "beautiful");
Consumer<String> onNextConsumer = new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.i(TAG, s);
    }
};
observable.subscribe(onNextConsumer);

这里写图片描述

例子:来一个简单的例子来了解事件的产生到消费、订阅的过程:从res/mipmap中取出一张图片,显示在ImageView上。

final ImageView ivLogo = (ImageView) findViewById(R.id.logo);
Observable.create(new ObservableOnSubscribe<Drawable>() {


    @Override
    public void subscribe(ObservableEmitter<Drawable> e) throws Exception {
        // 从mipmap取出一张图片作为Drawable对象
        Drawable drawable = ContextCompat.getDrawable(MainActivity.this, R.mipmap.ic_launcher);

        // 把Drawable对象发送出去
        e.onNext(drawable);
        e.onComplete();
    }
}).subscribe(new Observer<Drawable>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(Drawable value) {
        ivLogo.setImageDrawable(value);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onComplete() {

    }
});

这样就完成了一个简单的图片的设置
这里写图片描述

ObservableEmitter和Disposable

ObservableEmitter: ObservableEmitter可以理解为发射器,这个就是用来发出事件的,它可以发出三种类型的事件,通过调用emitter的onNext(T value)、onComplete()和onError(Throwable error)就可以分别发出next事件、complete事件和error事件。
注意:但是事件的发送是有一定的规定的,就好比寄快递也要有一定要求,不是什么都能寄的:

1.被观察者可以发送无限个onNext, 观察者也可以接收无限个onNext.
2.当Observable发送了一个onComplete后, Observable的onComplete之后的事件将会继续发送, 而Observer收到onComplete事件之后将不再继续接收事件.
3.当Observable发送了一个onError后, Observable中onError之后的事件将继续发送, 而Observer收到onError事件之后将不再继续接收事件.
4.Observable可以不发送onComplete或onError.
5.最为关键的是onComplete和onError必须唯一并且互斥, 即不能发多个onComplete, 也不能发多个onError, 也不能先发一个onComplete, 然后再发一个onError, 反之亦然

注: 关于onComplete和onError唯一并且互斥这一点, 是需要自行在代码中进行控制, 如果你的代码逻辑中违背了这个规则, 并不一定会导致程序崩溃. 比如发送多个onComplete是可以正常运行的, 依然是收到第一个onComplete就不再接收了, 但若是发送多个onError, 则收到第二个onError事件会导致程序会崩溃.当我们写多个onComplete时,不会报错

当我们又有onComplete又有onError时,发现在调用onComplete后会爆出异常

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(5);
        e.onNext(6);
        e.onNext(7);
        e.onNext(8);
        
        e.onError(new NullPointerException());
        e.onComplete();
    }
})

这是onComplete在onError前调用的情况
这里写图片描述

当我们写两个onError时,会先接受前面的所有事件,最后才报错
这里写图片描述

介绍了ObservableEmitter, 接下来介绍Disposable, 当调用dispose()方法时, 它就会将观察者和被观察者的联系切断, 从而导致观察者收不到事件.

注意: 调用dispose()并不会导致Observable不再继续发送事件, Observable会继续发送剩余的事件.
看一下下面这个例子:

Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            Log.d(TAG, "emitter 1");
            emitter.onNext(1);
            Log.d(TAG, "emitter 2");
            emitter.onNext(2);
            Log.d(TAG, "emitter 3");
            emitter.onNext(3);
            Log.d(TAG, "emitter 
  • 16
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
当然可以!以下是一个简单的 RxJava 示例: ```java import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; public class RxJavaDemo { public static void main(String[] args) { Observable<String> observable = Observable.just("Hello, World!"); Observer<String> observer = new Observer<String>() { @Override public void onSubscribe(Disposable d) { // 在订阅时被调用 System.out.println("onSubscribe"); } @Override public void onNext(String s) { // 当收到数据时被调用 System.out.println("onNext: " + s); } @Override public void onError(Throwable e) { // 当发生错误时被调用 System.out.println("onError: " + e.getMessage()); } @Override public void onComplete() { // 当完成时被调用 System.out.println("onComplete"); } }; observable.subscribe(observer); } } ``` 这个示例中,我们创建了一个简单的 Observable 对象,它只发射了一个字符串 "Hello, World!"。然后我们创建了一个 Observer 对象,它定义了在收到数据、发生错误或完成时的行为。最后,我们通过调用 `observable.subscribe(observer)` 来订阅 Observable。 运行这个示例,你将会看到以下输出: ``` onSubscribe onNext: Hello, World! onComplete ``` 这表明在订阅时,`onSubscribe` 被调用;然后收到了数据 "Hello, World!",`onNext` 被调用;最后,`onComplete` 被调用,表示完成了数据的发射过程。 请注意,这只是 RxJava 的一个简单示例,RxJava 还有很多更强大的操作符和功能可以使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的代码家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值