RxJava

# RxJava #
观察者observer和被观察者Observable

       //被观察者的创建
       Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
               //emitter是一个发射器,可以调用onNext(),onComplete(),onError(),后面这两个事件是唯一的,只能存在一个,不能发送多个onComplete()和多个onError()和两者都存在
               //调用onNext()会依次的发送该数据,当调用onComplete()的时候如果后面还有onNext(),依然
               //会发送,但是下面observer也会一次接收这些数据,当接收到onComplete()事件时,就不再接收了
                emitter.onNext("我"); 
                emitter.onNext("不");
                emitter.onNext("知"); 
                emitter.onNext("道");
                emitter.onComplete();
                Log.e("qiukailong","还发送吗?");
                emitter.onNext("这");
                emitter.onNext("是");
                emitter.onNext("什");
                emitter.onNext("么");
                Log.e("qiukailong","发送完成");
            }
           });


          Observer<String> observer = new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                //当在onNext()调用d.dispose()后,将不再接收所发送的事件,但是emitter依然会发送未发送完的事件
            }

            @Override
            public void onNext(String value) {
                Log.e("qiukailong",value);
                mTv.setText(value); //这个使用textview显示文字的时候只会显示最后一个接收到的,因为把之前的给替换了
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
              Log.e("qiukailong","complete");
            }
           };

           observable.subscribe(observer); //在这里订阅,只有订阅了才会发送数据,所以订阅的时候就可以写成链式的
打印结果
! [](http://i.imgur.com/wIdUagS.png)
! [](http://i.imgur.com/iL1V9hq.png)
subscribe()有多个重载的方法:
  - 不带任何参数的subscribe(),不管发送什么都不接收
  - 带有一个Consumer参数的方法表示observer只关心onNext事件, 其他的事件不接收, 因此如果只需要onNext事件可以这么使用这个
以上的是在同一个线程中发送和接收数据,一般会有耗时联网等的操作然后再更新UI,耗时的要在子线程中进行,更新UI就要在主线程中了,所以就可以用RxJava内置的线程调度器
       /*
                * subscribeOn()可以调用多次,但是只有第一次有效
                * observeOn()可以调用多次,每调用一次就会切换一次
                * 这是指定发送事件所在的线程
                * Schedulers.io() 代表io操作的线程, 通常用于网络,读写文件等io密集型的操作
                * Schedulers.computation() 代表CPU计算密集型的操作, 例如需要大量计算的操作
                * Schedulers.newThread() 代表一个常规的新线程
                * AndroidSchedulers.mainThread() 代表Android的主线程
                * */
        observable.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
如果在请求的过程中Activity已经退出了,这个时候如果回到主线程去更新UI,那么APP肯定就崩溃了,Disposable是个开关,调用它的dispose()方法时就会不再接收事件,既然收不到事件,那么也就不会再去更新UI了,因此可以在Activity中将这个Disposable保存起来,当Activity退出时,切断它即可.
如果有多个Disposable,RxJava中已经内置了一个容器CompositeDisposable,每当我们得到一个Disposable时就调用CompositeDisposable.add()将它添加到容器中,在退出的时候,调用CompositeDisposable.clear()即可切断所有的接收事件.
网络或者数据库操作时候就在Observable中操作,订阅的时候设置发送数据的线程为子线程
如果发送的数据类型不是我们要接收的类型,比如发送的是int类型,我们想要String类型的,就可以通过map,map是RxJava中最简单的一个变换操作符了, 它的作用就是对上游发送的每一个事件应用一个函数, 使得每一个事件都按照指定的函数去变化.
 ! [](http://i.imgur.com/hcB5ilf.png)
         Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
            }
        }).map(new Function<Integer, String>() {

            @Override
            public String apply(Integer integer) throws Exception {
                return "Rxjava" + integer; //这就是要发送的数据,int
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Toast.makeText(MainActivity.this, "看这里" + s, Toast.LENGTH_LONG).show(); //String
            }
        });
FlatMap flatMap是一个非常强大的操作符,FlatMap将一个发送事件的上游Observable变换为多个发送事件的Observables,然后将它们发射的事件合并后放进一个单独的Observable里.
! [](http://i.imgur.com/g3bHNLv.png)
       Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onNext(4);
            }
        }).flatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++){
                    list.add("我 是 =" + integer);
                }
                    return Observable.fromIterable(list).delay(10 , TimeUnit.SECONDS);//延时
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                    Log.e("qiukailong", s);
            }
        });
打印结果
! [](http://i.imgur.com/IfJSrss.png)
使用flatmap,flatMap并不保证事件的顺序,如果需要保证顺序则需要使用concatMap.把上面的flatmap换成concatMap就可以了,打印结果
! [](http://i.imgur.com/dTcFSjx.png)
zip操作符,Zip通过一个函数将多个Observable发送的事件结合到一起,然后发送这些组合到一起的事件. 它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。
 ! [](http://i.imgur.com/Yt0naZ3.png)
创建两个Observable,在不同的线程中发送事件
       final Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                Log.e("qiukailong", "1");
                emitter.onNext(2);
                Log.e("qiukailong", "2");
                emitter.onNext(3);
                Log.e("qiukailong", "3");
                emitter.onNext(4);
                Log.e("qiukailong", "4");
            }
        }).subscribeOn(Schedulers.io());  //在子线程中
        final Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("A");
                Log.e("qiukailong", "A");
                emitter.onNext("B");
                Log.e("qiukailong", "B");
                emitter.onNext("C");
                Log.e("qiukailong", "C");
                emitter.onComplete();
                emitter.onNext("D");
                Log.e("qiukailong", "D");
            }
        }).subscribeOn(Schedulers.io()); //在子线程中

        Observable.zip(observable1, observable2, new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer integer, String s) throws Exception {
                return integer + s;
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e("qiukailong", "onSubscribe");
            }

            @Override
            public void onNext(String value) {
                Log.e("qiukailong", value);
            }

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

            @Override
            public void onComplete() {
                Log.e("qiukailong", "onComplete");
            }
        });
打印结果
! [](http://i.imgur.com/nf0QX0Q.png)
使用zip时,Observable1和Observable2发送数据,如果Observable1发送快,而Observable2发送慢,Observable1的事件会存储到某个地方,但是如果事件过多就会导致omm,因为存储的数据太多,其他情况发送和接收事异步的话也会出现oom
还有filter操作符,过滤掉自己不想要的
sample操作符,设定每隔指定时间从发送事件那里取出事件
Flowable和Subscriber
      final Flowable<Integer> flowable = Flowable.create(new FlowableOnSubscribe<Integer>() {
            //flowable中有大小为128的储存器,如果subscribe没有 s.request(Long.MAX_VALUE)写这个,就会把要发送的事件储存起
            //来,如果通过外部调用的 s.request(Long.MAX_VALUE)时候指定数量,依然可以取出事件
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                Log.e("qiukailong","1");
                emitter.onNext(2);
                Log.e("qiukailong", "2");
                emitter.onNext(3);
                Log.e("qiukailong", "3");

            }
        }, BackpressureStrategy.ERROR); //BackpressureStrategy.BUFFER没有大小限制超过128也没事
                                        //BackpressureStrategy.DROP 把存不下的事件丢弃
                                        //BackpressureStrategy.LATEST只保留最新的事件

        Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onSubscribe(Subscription s) {
                Log.e("qiukailong", "onSubscribe");
                //如果不想接收事件就调用s.cancel();
                s.request(Long.MAX_VALUE); //代表能处理多少事件,如果发送事件大于这个处理数量,就会抛出
                // onErrorio.reactivex.exceptions.MissingBackpressureException: create: could not emit value due to lack of requests
            }

            @Override
            public void onNext(Integer integer) {
                Log.e("qiukailong", integer + "");

            }

            @Override
            public void onError(Throwable t) {
                Log.e("qiukailong", "onError" + t);
            }

            @Override
            public void onComplete() {
                Log.e("qiukailong", "onComplete");
            }
        };
        flowable.subscribe(subscriber);
        //当接收和发送在同意线程中,可以通过emitter.requested()获取接收事件的数量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值