Rxjava的使用_1

         最近工作用Rxjava,发现有些东西忘记了,翻了翻资料,才想起来。可能是年纪大了记性不好,所以在这里写下来,以后在需要查资料就不用去到处找了,直接看自己的博客就好了。

依赖

在安卓中,除了依赖RxJava外,还需要依赖一下RxAndroid

compile 'io.reactivex.rxjava2:rxandroid:2.1.0'
compile 'io.reactivex.rxjava2:rxjava:2.1.0'

鉴于RxJava源码比较多,本系列不会分析源码,主要介绍一些常用到的东西

1. RxJava简要介绍

RxJava中有三个关键点
Observable,被观察者
Observer,观察者
subscribe,建立订阅关系

在观察者模式中,一般都是观察者订阅被观察者
但在RxJava中,是Observable.subscribe(Observer)

被观察者有变化,观察者就会知道。

 

有一个类比水管的说法,水管说:

RxJava事件流向.png

Observable,上游水管
Observer,下游水管
subscribe,连接上下游的水管

水管接上之后,上游水管里的水流动,下流水管里的水就会流动。

2. 基本使用

废话不多说,先来一段代码感受一下

 //关注点1
    Observable<String> observable=Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            Log.d("TAG","subscribe");
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onNext("3");
            emitter.onComplete();
        }
    });

    //关注点2
    Observer<String> observer=new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.d("TAG","onSubscribe");

        }

        @Override
        public void onNext(String s) {
            Log.d("TAG",s);
        }

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

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

    //关注点3
    observable.subscribe(observer);

这段代码的执行结果

D/TAG: onSubscribe
D/TAG: subscribe
D/TAG: 1
D/TAG: 2
D/TAG: 3
D/TAG: onComplete

站在水管的角度
把关注点1比喻成一根水管,处在上游
把关注点2也比喻成一根水管,处在下游
关注点3就是连接这两根水管的一个媒介,通过该媒介关注点1和关注点2就连通了。

我们在来看看剩下的两个比较陌生的类
ObservableEmitter和Disposable
ObservableEmitter
这是一个接口,继承自Emitter接口,翻译过来就是发射器的意思,而它就是用来发出事件的,通过调用emitter的onNext(T value),
onError(Throwable t)和onComplete()分别用来发生next事件,error事件和complete事件。

下面来总结一下事件的发送接收规则

  • 事件是发送一个,接收一个,然后才发送下一个。
  • 上游可以发送无限个next事件,下游也可以接收无限个next事件。
  • 当上游发送complete或者error事件后,下游不会在接收complete或者error事件之后的事件,但上游会将全部事件都发送完。
  • 上游的complete和error事件必须唯一且互斥,否则可能相应的事件不会被下游接收到,并且可能会发生手机崩溃的情况。

Disposable(这一点不是最常用的一部分,了解一下就好了)
Disposable是一个接口,里面就两个方法

 void dispose();
 boolean isDisposed();

修改关注点1和关注点2的代码

  //关注点1
    Observable<String> observable=Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            Log.d("TAG","subscribe");
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onComplete();
            emitter.onNext("3");
            Log.d("TAG","emitter 3");
        }
    });

    //关注点2
    Observer<String> observer=new Observer<String>() {
        Disposable disposable;
        @Override
        public void onSubscribe(Disposable d) {
            Log.d("TAG","onSubscribe");
            disposable=d;

        }

        @Override
        public void onNext(String s) {
            Log.d("TAG",s);
            if(s.equals("1")){
                disposable.dispose();
                Log.d("TAG", "isDisposed : " + disposable.isDisposed());
            }
        }

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

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

输出结果

D/TAG: onSubscribe
D/TAG: subscribe
D/TAG: 1
D/TAG: isDisposed : true
D/TAG: emitter 3

结果分析
当在下游调用disposable.dispose()方法时,下游将不会在接收后续的事件,但上游还是会将全部事件发送完毕。
这里的dispose就相当于将水管切断了,因此接收不了后续事件。

链式调用(上面讲了那么多,其实最重要的事这一部分,我们常用的就是这一部分。)
我们来稍微修改一下之前的写法,就变成了RxJava流行的链式调用写法了。

 Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {

        }
    }).subscribe(new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {
            
        }

        @Override
        public void onNext(String s) {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    });

上面的写法就是常用的链式写法,但是还有一点小问题,就是默认被观察者观察者都是在主线程中运行的,如果我们用它来做耗时操作,就要放在子线程中,操作完成之后又要转到主线程去更新UI,这样又要用handler,线程切换比较麻烦。其实Rxjava已经为我们处理了。

observable有两个方法分别指定被观察者观察者代码运行 线程。

observable.subscribeOn(Schedulers.io());//指定被观察者运行在子线程。(上游水管)
observable.observeOn(AndroidSchedulers.mainThread());//指定观察者运行在主线程。(下游水管)

RxJava已经为我们提供了一下几个Scheduler

  • Schedulers.immediate():直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
  • Schedulers.newThread():总是启用新线程,并在新线程执行操作。
  • Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
  • Schedulers.computation():计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
  • AndroidSchedulers.mainThread():它指定的操作将在 Android 主线程运行。

可以根据自己的需要去选择被观察者和观察者所在的线程。

链式编程

 Observable.create(new ObservableOnSubscribe<Object>() {
                    @Override
                    public void subscribe(ObservableEmitter<Object> e) throws Exception {
                        Log.i("ceshi", "subscribe " + Thread.currentThread().getName());
                        e.onNext("好好学习,天天向上");
                    }
                }).subscribeOn(Schedulers.io())//指定被观察者运行的线程。
                        .observeOn(AndroidSchedulers.mainThread())//指定观察者运行的线程。
                        .subscribe(new Observer<Object>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.i("ceshi", "onSubscribe d = " + d + Thread.currentThread().getName());
                            }

                            @Override
                            public void onNext(Object value) {
                                Log.i("ceshi", "onNext value = " + value + "  " + Thread.currentThread().getName());

                            }

                            @Override
                            public void onError(Throwable e) {
                                Log.i("ceshi", "onError e = " + e.toString() + "  " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onComplete() {
                                Log.i("ceshi", "onComplete  ");
                            }
                        });

运行的结果

11-29 10:50:58.272 23384-23384/com.airbridge.rxjavademo I/ceshi: onSubscribe d = 0main
11-29 10:50:58.274 23384-23523/com.airbridge.rxjavademo I/ceshi: subscribe RxCachedThreadScheduler-1
11-29 10:50:58.278 23384-23384/com.airbridge.rxjavademo I/ceshi: onNext value = 好好学习,天天向上  main
11-29 10:50:58.278 23384-23384/com.airbridge.rxjavademo I/ceshi: onComplete  

这就是我们常用的链式编程方式,下一篇我们来讲一下背压问题。下一篇讲背压的博客:Rxjava的使用_2(背压问题)

如果需要上面的源码,可以去下载 RxjavaDemo.zip

本篇中有一部分截图和代码是从这个https://www.jianshu.com/p/9561ebdc5c0b哥们儿博客里面借用的。大家也可以去看的博客。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值