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方法.

一旦下游處理了上游的一個事件,那麼緩存池裏就會減一個

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