RxJava2 基础详解

RxJava2 基础详解

标签: 网络框架


什么是RxJava

RxJava是Java的响应式编程的扩展,还有一个关键词“异步”

RxJava的自我介绍是:a library for composing asynchronous and event-based programs using observable sequences for the Java VM(一个对于构成使用的Java虚拟机观察序列异步和基于事件的程序库)。很好的阐述了重点“异步”

github:https://github.com/ReactiveX/RxJava

使用RxJava的好处

随着项目代码量慢慢增加,逻辑复杂程度也会渐渐加强,使用RxJava可以帮助我们不管程序逻辑怎样复杂始终保持简洁,因为在调度过程比较复杂的情况下,异步代码经常既难写也难被读懂

RxJava的基本概念

  • Observable:发射源,英文释义“可观察的”,在观察者模式中称为“被观察者”或“可观察对象”;
  • Observer:接收源,英文释义“观察者”,没错!就是观察者模式中的“观察者”,可接收ObservableFlowable发射的数据;
  • Flowable:这个也是“被观察者”,咦,怎么又有一个“被观察者”,这个是RxJava2.0新出的用以支持“背压”,关于背压就不做过多解释,可以看关于RxJava最友好的文章——背压(Backpressure)文章;
  • Subscriber:“订阅者”,也是接收源,其实也就是“观察者”,支持背压的话以这个和Flowable搭配使用,也可以用来当作Observer使用;
  • Subscription:Observable调用subscribe()方法绑定(订阅)对象,同样有unsubscribe()方法,可以用来取消订阅事件;
  • Schedulers:调度器,对于事件产生(Observable)在什么环境和事件处理(Observer)在什么环境进行调度;

添加依赖

//RxJava的依赖包
compile 'io.reactivex.rxjava2:rxjava:2.0.3'
//RxAndroid的依赖包
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

基本流程

  • 创建被观察者
Observable observable = Observable.create(new Observable.OnSubscribe<String>(){
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Hello");                 //onNext-发射数据
                subscriber.onNext("RxJava");
                subscriber.onCompleted();                   //onCompleted-发射完毕的标记
            }
        });
  • 创建观察者
Observer<String> observer = new Observer<String>() {
        @Override
        public void onCompleted() {
            //被观察者调用onCompleted()代表事件发射完毕,并走向这里
            Log.i(TAG,"数据发射完毕");
        }
        @Override
        public void onError(Throwable e) {
            //发射数据过程中出错会走向这里
            Log.i(TAG,"数据出错,错误信息:" + e.getMessage());
        }
        @Override
        public void onNext(String s) {
            //发射的数据走向这里
            Log.i(TAG,"数据--->"+s)
        }
    };

观察者有了,被观察者也有了,剩下的就将他们绑定在一起,也就是订阅让他们产生联系;

  • 订阅
被观察者-----订阅-----观察者
observable.subscribe(observer);

这我就纳闷了,为什是‘被观察者’去订阅‘观察者’,不是应该反过来的吗?是这样的,逻辑没有错,这样是为了保证链式API调用风格(建造者模式),因为大家想,观察者模式的产生是先有事件产生之后再有‘观察者’对其处理;总不能说什么事都没有而先有‘观察者’处理事件(处理什么事件你们估计也会懵逼),再之后有事件产生;
举个例子:就好比你去超市买一包香烟,正常逻辑是老板问你买什么?你回答买一包什么烟,然后老板就给你什么烟;总不能你一进超市,老板直接给你一包烟,再去问你要什么烟,这样事件的逻辑就不通了
到这时候大家还是会说:是啊,先有事件产生再有事件处理,但还是没解释被观察者订阅观察者这个逻辑啊;
之前不是说了吗,为保证链式API调用风格(建造者模式),如果你想的是观察者订阅被观察者的话,那你是不是得先写观察者?先写观察者?那这样的话是不是与事件逻辑走向相勃;其实这仅仅只是为了保证链式API调用风格,内部实际上还是观察者订阅被观察者;所以大家懂就好。

Tips:基本流程就走到这了

调度 Scheduler

  • 调度在之前稍微提到,这是RxJava用以切换线程的调度器,虽然RxJava是异步的,但在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用subscribe(),就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件。如果需要切换线程,就需要用到 Scheduler (调度器)。
调度器类型效果
Schedulers.computation()用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量
Schedulers.from(executor)使用指定的Executor作为调度器
Schedulers.immediate()在当前线程立即开始执行任务
Schedulers.io()用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io( )默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器
Schedulers.newThread( )为每个任务创建一个新线程
Schedulers.trampoline( )当其它排队的任务完成后,在当前线程排队开始执行
AndroidSchedulers.mainThread()是RxAndroid适配于Android系统下的一个方法,用于指定执行在Android主线程中
//指定事件产生在io线程中执行
.subscribeOn(Schedulers.io())
//指定事件处理在安卓主线程中执行
.observeOn(AndroidSchedulers.mainThread())

RxJava操作符

RxJava并不仅仅只有上面所说的基本能力,他的操作符才是重点。

  • just
    可以说是偷懒必备,just可以接收1~9个参数
//使用just按顺序onNext发射括号的数据,并在发射完毕之后自动调用onCompleted()
Observable.just("Hello","RxJava")           //是不是省略了很多代码
        .subscribe(new Observer<String>() {
            @Override
            public void onCompleted() {
                //发射结束调用这个方法
            }
            @Override
            public void onError(Throwable e) {
                //出现错误会调用这个方法
            }
            @Override
            public void onNext(String s) {
                //发射的数据在这个方法
            }
        );
  • from
    from接收一个数组或集合对象,按顺序发送对象中的每个子元素(item),just也可以接收集合,但just发送的是整个集合对象
//定义一个数组
String[] str = {"Hello","RxJava"};
//from自动拿出数组str中的每个子元素发送出去
Observable.from(str)
        .subscribe(new Observer<String>() {
            @Override
            public void onCompleted() {
                //发射结束调用这个方法
            }
            @Override
            public void onError(Throwable e) {
                //出现错误会调用这个方法
            }
            @Override
            public void onNext(String s) {
                //发射的数据在这个方法
            }
        );
  • map
    产生事物不是理想的目标结果,可以用map对其在发射之前中转操作
//比如被观察者发送一个图片路径,但观察者要的是直接一张图片
Observable.just(getFilePath())
            //使用map操作来完成类型转换
            .map(new Func1<String, Bitmap>() {      //指定泛型,String是图片路径,Bitmap是图片
              @Override
              public Bitmap call(String s) {
                //将图片路径转换成一张图片
                return createBitmapFromPath(s);
              }
          })
            .subscribe(new Subscriber<Bitmap>() {
                @Override
                public void onCompleted() {
                    //发射完毕调用此方法
                }

                @Override
                public void onError(Throwable e) {
                    //出现错误会调用这个方法
                }
                @Override
                public void onNext(Bitmap s) {      //发射过来的就是一张图片
                    //直接显示图片
                }
            );
  • flatmap
    这个就比较难懂了,简单说就是将每个Observable产生的事件里的信息再包装成新的Observable传递出来
    举个例子,查找一个学校的所有班级的每个学生的姓名,那就可以这样:
//创建被观察者,获取所有班级
 Observable.from(school)
                .flatMap(new Func1<Class, Observable<String>>() {
                    @Override
                    public Observable<String> call(Class Class) {
                        //每个班级的所有学生姓名装成一个数组或集合,再封成新的Observable,通过from这个集合发射数据
                        return Observable.from(Class.getStudentName());
                    }
                })
                .subscribe(new Subscriber<String>() {
                        @Override
                        public void onCompleted() {
                            //发射完毕,调用此方法
                        }

                        @Override
                        public void onError(Throwable e) {
                            //出现错误会调用这个方法
                        }
                        @Override
                        public void onNext(String string) {
                            //发射过来的是每个学生的姓名
                        }
                    );

结尾

对于RxJava只写到这了,毕竟本人对于RxJava只懂这么多。

后记

本人那渣渣文字功底确实不好见人,有些说明措辞是参照部分大牛的说法进行揉杂的,结果就这样了
可以参照关于 RxJava 最友好的文章—— RxJava 2.0 全新来袭的文章再去仔细看看,很好理解的一篇文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值