Rxjava从使用到原码的解析九: Rxjava背压策略

Rxjava背压策略由来:

RxJava1.X的时候,还没有背压模式,在我们上游就可以无限发射事件出来,当我们下游处理不过来的时候,就会造成内存泄漏

RxJava2.0之后,作者就增加了背压策略-->>Flowable,他拉功能跟Obserable功能基本一样

什么时候用Obserable,什么时候用Flowable

当上游有大量事件发射的时候,有时会导致下游处理不过来时用Flowable

不使用线程调度

Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    e.onNext(i);
                }
                e.onComplete();
            }
        }, BackpressureStrategy.BUFFER)
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        
                    }

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

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

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

上面代码中,在上游不断的发送事件,这种大量事件发射经过测试会导致APP内存泄漏,

当在下面方法中加入一行代码

                    @Override
                    public void onSubscribe(Subscription s) {
                        mSubscription = s;
                        s.request(5);
                    }

就会输出下面内容onNext: 0
onNext: 1
onNext: 2
onNext: 3
onNext: 4
onError: create: could not emit value due to lack of requests

从上面可以看出,下游每一次接收多少事件是由下游的onSubscribe这个方法来控件的,

如果同步不执行request这个方法的时候,就会崩溃

下面加下线程调度

 Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                    e.onNext(i);
                }
                e.onComplete();
            }

        }, BackpressureStrategy.BUFFER)//上游不停的发射大量事件,下游阻塞处理不过来,就会放入缓存池,如果池满了就会抛出异常
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        mSubscription = s;
                        s.request(129);
                    }

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

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

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

    }

    Subscription mSubscription;

    public void rx02(View view) {
        if (mSubscription != null) {
            mSubscription.request(10);
        }
    }

上面我们在onSubscribe方法中将mSubscription = s; 放在btn2里面

当第一 次执行时,会输出128次,然后我们每点一下btn2就会再放出10个事件,,如果缓存中没有的话,上游就会发射onCompletegker

如果异步的进修,我们可以把发射事件直接由外部点击发身

 

总结:

同步情况:

Rxjava在同步情况下上游发送一个事件,然后下游接收一个事件,再上游戏发射第二个事件以些下去.

所以Flowable发送2亿个事件,如果下游没有去request的话,那么事件就会一直处理等待过程,最终就会抛出异常,

在同步的情况下,外置调用request方法没有效果

异步情况:

Rxjava在异步情况下上游发射多少个事件跟下游接没接没关系,不管下游有没有接收上游都会不断的接收事件,所以Flowable发射2亿个事件,也不会造成APP崩溃.只是如果没有执行request的话,下游就不会响应事件而于.

在异常的情况下,可以外置调用request方法.

一旦下游处理了上游的一个事件,那么缓存池里就会减一个

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章