Rxjava2进阶使用篇

本文介绍了RxJava2中的线程切换实战,详细讲解了背压模式及其策略,包括丢弃事件和缓存事件。此外,还探讨了Flowable在处理大量事件时的优势,并展示了RxJava与Retrofit的配合使用,以及Java泛型的上下限概念。
摘要由CSDN通过智能技术生成

Rxjava线程切换实战

  1. 异步线程区域
    Schedulers.io() :代表io流操作,网络操作,文件流,耗时操作
    Schedulers.newThread() : 比较常规的,普普通通
    Schedulers.computation() : 代表CPU 大量计算 所需要的线程
  2. AndroidSchedulers.mainThread() : 专门为Android main线程量身定做的
  3. 给上游分配多次,只会在第一次切换,后面的不切换了(忽略)
  4. 给下游分配多次,每次都会去切换

RxJava背压模式

背压模式的由来:
RxJava1.X的时候,还没有背压模式, 我们的上游不停的发射,我们的下游处理不过来,就会照成内存泄漏
RxJava2.X之后,增加背压模式,Observable Flowable(解决背压)
Observable — > Flowable(解决背压)

什么时候用Observable<—>Observer, 什么使用Flowable<—>Subscriber ?
答:发射的事件,大量的事件(1000个),并且考虑到下游处理不过来,就需要使用Flowable

背压策略
  • BackpressureStrategy.ERROR 如果池子满了,就会抛出异常
  • BackpressureStrategy.BUFFER 如果池子慢了,“等待”下游来接收事件处理
  • BackpressureStrategy.DROP 如果池子满了,就会把后面发射的事件丢弃(不常用)
  • BackpressureStrategy.LATEST 只存储 128个事件(不常用)
背压例子
Flowable.create(new FlowableOnSubscribe<Integer>() {
    @Override
    public void subscribe(FlowableEmitter<Integer> e) throws Exception {
        // todo 1 上游不停的发射大量事件
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            e.onNext(i); // todo 1
        }
        e.onComplete();
    }
}, BackpressureStrategy.BUFFER)

 .subscribeOn(Schedulers.io()) // 给上游分配异步线程
 .observeOn(AndroidSchedulers.mainThread())     // 给下游分配 主线程

.subscribe(
        // 完整版本的下游 观察者
        new Subscriber<Integer>() {
            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                // 如果同步的 不执行此s.request();,(等待下游,发现下游没有去处理)会抛出异常, 外界在调用subscription.request(10); 无效果
                // 如果是异步的,不执行此s.request();,不会发生异常(上游不会等待下游)不会发生异常, 外界在调用subscription.request(10); 是ok的
                // s.request(100);  // 只请求输出 100次,给下游打印
            }

            @Override
            public void onNext(Integer integer) {

                // todo 2 下游阻塞了 处理不过来
                try {
                    Thread.currentThread().sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


                // TODO 一旦下游处理了一次上游的事件,缓存池 - 1
                Log.d(TAG, "onNext: " + integer);
            }

            // onError: create: could not emit value due to lack of requests  上游还有剩余的事件,无法处理,因为没有去请求
            @Override
            public void onError(Throwable t) {
                Log.d(TAG, "onError: " + t.getMessage());
            }

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

RxJava之Flowable讲解

  1. FlowableObserverable使用几乎一致,依葫芦画瓢就可。
  2. 切断下游的方式略有不同,如下:
    • ObservableObserver下游 – onSubscribe(Disposable d)切断下游(水管)
    • FlowableSubscriber下游 – onSubscribe(Subscription s) 取出(s.request(5))事件 给下游接收使用

RxJava配合Retrofit

需求:一行代码写完需求流程 (从上往下)

  1. 请求服务器,执行注册操作(耗时)切换异步线程
  2. 更新注册后的所有 注册相关UI - main 切换主线程
  3. 请求服务器,执行登录操作(耗时)切换异步线程
  4. 更新登录后的所有 登录相关UI - main 切换主线程
MyRetrofit.createRetrofit().create(IRequestNetwork.class)
        //  1.请求服务器注册操作  // todo 第二步 请求服务器 注册操作
        .registerAction(new RegisterRequest()) // Observable<RegisterResponse> 上游 被观察者 耗时操作
        .subscribeOn(Schedulers.io()) // todo 给上游分配异步线程

        .observeOn(AndroidSchedulers.mainThread()) // todo 给下游切换 主线程
        // 2.注册完成之后,更新注册UI

        /**
         *  这样不能订阅,如果订阅了,就无法执行
         *      3 马上去登录服务器操作
         *      4.登录完成之后,更新登录的UI
         *
         *  所以我们要去学习一个 .doOnNext(),可以在不订阅的情况下,更新UI
         */
        .doOnNext(new Consumer<RegisterResponse>() { // 简单版本的下游
            @Override
            public void accept(RegisterResponse registerResponse) throws Exception {
                // todo 第三步 更新注册相关的所有UI
                // 更新注册相关的所有UI
                tv_register_ui.setText("xxx");
                // .......
            }
        })
        // 3.马上去登录服务器操作 -- 耗时操作
        .subscribeOn(Schedulers.io()) // todo 分配异步线程
        .flatMap(new Function<RegisterResponse, ObservableSource<LoginResponse>>() {
            @Override
            public ObservableSource<LoginResponse> apply(RegisterResponse registerResponse) throws Exception {
                // 还可以拿到 注册后的响应对象RegisterResponse
                // 执行耗时操作
                // 马上去登录服务器操作 -- 耗时操作
                Observable<LoginResponse> observable = MyRetrofit.createRetrofit().create(IRequestNetwork.class)
                        .loginAction(new LoginRequest());  // todo 第四步 马上去登录服务器操作 -- 耗时操作
                return observable;
            }
        })
        // 4.登录完成之后,更新登录的UI
        .observeOn(AndroidSchedulers.mainThread()) // // todo 给下游切换 主线程
        .subscribe(new Observer<LoginResponse>() {
            @Override
            public void onSubscribe(Disposable d) {
                // todo 第一步
                progressDialog.show();
            }

            @Override
            public void onNext(LoginResponse loginResponse) {
                // 更新登录相关的所有UI
                // todo 第五步 更新登录相关的所有UI
                tv_login_ui.setText("xxxx");
                // ...........
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                // todo 第六步
                progressDialog.dismiss(); // 结束对话框 ,整个流程完成
            }
        });

看RxJava另外一种的执行流程
初始点 开始点 订阅

  1. onSubscribe
  2. registerAction(new RegisterRequest())
  3. doOnNext 更新注册后的 所有UI
  4. flatMap执行登录的耗时操作
  5. 订阅的观察者 下游 onNext 方法,更新所有登录后的UI
  6. progressDialog.dismiss()

Java泛型的上下限

由于RxJava大量的使用到了泛型,所有学习
如果我们不指定泛型类型,默认就是Object,Object的扩展集

  1. ? super F 下限:F or F 所有父类 都可以,所以属于把下面的类型限限制了,下面的类型不能低于F,不能是F的子类,否则编译不通过。
  2. ? extends F 上限:F or F 所有子类 都可以,所有属于把上面的类型给限制了,上面的类型不能高于F,不能是F的父类,否则编译不通过。
    一句话记住(? super F: F 或者 F的所有父类 都可以, ? extends F: F 或者 F的所有子类都可以)
  3. 可写模式<?super F> 可写,不完全可读
    因为设定了下限为F类型,所以F和F类型的的子类一定都是一个F,它们都是可写的。但是F的父类的写入就不是合法的,因为这个泛型可能就是F,不能用一个子类的引用指向一个父类的对象。因为没有上限,所以你只能保证能读到Object的子类。
  4. 可读模式<? extends F> 可读,不可写
    因为不能确定这个泛型的下限,自然不可写。但这是可读的,因为读到的一定是F或F的子类。

参考链接


架构师系列文章一览

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT小瓯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值