RxJava详解(基于2.X版本的背压详解)(下)

RxJava背压基础讲解

https://blog.csdn.net/weixin_37730482/article/details/78085190

 

 

本章节继续讲述RxJava的背压问题

 

 

 

 

 

一.控制 观察者 接收事件的速度

 

<1> 前言

 

被观察者发送消息的速度和观察者接收消息的速度不匹配时,可以控制观察者接收消息的速度


原理是 不管被观察者发送了多少条数据,观察者仅根据自身情况选择接收几条消息。哪怕被观察者发送量100条数据,若观察者仅需要两条消息,则只接收两条消息。忽略另外98条消息。

 

 

 

<2> 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);

        method();
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                /**
                 * 测试 被观察者发送五条消息
                 * */

                if (!e.isCancelled()) {
                    for (int i = 0; i < 5; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribeOn(Schedulers.io())//被观察者在io线程中进行
                .observeOn(AndroidSchedulers.mainThread())//观察者在主线程中进行
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                        mSubscription.request(4);//测试 被观察者发送五条消息 观察者只接收四条
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

 

 

<3> 结果

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据


D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   3   波数据

 

 

<4> 说明

被观察者发送五条消息。观察者通过onSubscribe方法中参数Subscription的request(number)方法设置只接收number即四条消息。

 

 

 

<5> 重要说明&异步订阅

Flowable抽象类创建被观察者方式  如果被观察者和观察者是异步订阅的 如果不设置

mSubscription.request(N);//设置 观察者只接收N条数据

则说明 观察者不接收消息。此时 被观察者仍然可以发送消息。并将消息存在缓存区等待观察者需要时再取出。即调用

mSubscription.request(N);//设置 观察者只接收N条数据

方法。

 

(1) 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        findView();
        method();
    }

    /**
     * 初始化各种View
     */

    private void findView() {
        TextView textView = findViewById(R.id.activity_rxjava_textview);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != mSubscription) {
                    mSubscription.request(4);//观察者只接收四条
                }
            }
        });
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                /**
                 * 测试 被观察者发送五条消息
                 * */

                if (!e.isCancelled()) {
                    for (int i = 0; i < 5; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribeOn(Schedulers.io())//被观察者在io线程中进行
                .observeOn(AndroidSchedulers.mainThread())//观察者在主线程中进行
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

(2) 结果

默认

无打印 即无消息接收

 

点击按钮 点击第一次 取出四条消息

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   3   波数据

 

点击按钮 点击第二次 取出剩余消息并执行onComplete方法

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   4   波数据

D/TAG: Flowable创建被观察者 观察者 onComplete方法 

 

点击按钮 点击第三四五...次 

无打印 即无消息接收。

 

 

 

 

<6> 重要说明&同步订阅

 

同步订阅,即被观察者和观察者处在同一线程中同步订阅关系中没有缓存区

 

同步订阅&异步订阅区别

订阅关系说明
同步订阅观察者和被观察者处在同一线程。被观察者每发送一条消息。必须等到观察者接收后才会发送下一条消息。
异步订阅观察者和被观察者处在不同的线程。被观察者不需要等待观察者处理消息后再发送下一条消息,而是不断发送直到发送消息完毕。

 

 

 

 

 

 

 

 代码

 

[1] 被观察者发送的消息数和观察者设置接收的消息数一致时

 

(1) 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        method();
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                /**
                 * 测试 被观察者发送五条消息
                 * */

                if (!e.isCancelled()) {
                    for (int i = 0; i < 5; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                        Log.d("TAG", "Flowable创建被观察者 被观察者发送数据 i----:" + i);
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                        mSubscription.request(5);//观察者接收五条
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

 

(2) 结果

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:0




D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:1




D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:2



D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   3   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:3



D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   4   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:4



D/TAG: Flowable创建被观察者 观察者 onComplete方法 

 

(3) 综上所述,同步订阅情况下不会出现被观察者发送事件速度 > 观察者接收事件速度的情况。可是,却会出现被观察者发送事件数量 > 观察者接收事件数量的问题。

 

 

[2] 被观察者发送的消息数和观察者设置接收的消息数不一致时

 

(1) 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        method();
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                /**
                 * 测试 被观察者发送五条消息
                 * */

                if (!e.isCancelled()) {
                    for (int i = 0; i < 5; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                        Log.d("TAG", "Flowable创建被观察者 被观察者发送数据 i----:" + i);
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                        mSubscription.request(3);//观察者接收三条
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

即 被观察者发送五条数据 观察者只接收三条消息。

 

 

(2) 结果

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:0



D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:1



D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 被观察者发送数据 i----:2



D/TAG: Flowable创建被观察者 被观察者发送数据 i----:3



D/TAG: Flowable创建被观察者 被观察者发送数据 i----:4

 

(3) 综上所述 对于没有缓存区概念的同步订阅关系来说,单纯采用控制观察者的接收事件数量(响应式拉取)还是会出现问题。

 

 

 

[3] 点击时再执行观察者的取方法

 

(1) 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        findView();
        method();
    }

    /**
     * 初始化各种View
     */

    private void findView() {
        TextView textView = findViewById(R.id.activity_rxjava_textview);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != mSubscription) {
                    mSubscription.request(4);//观察者只接收四条
                }
            }
        });
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                /**
                 * 测试 被观察者发送五条消息
                 * */

                if (!e.isCancelled()) {
                    for (int i = 0; i < 5; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

 

(2) 结果

 

默认

无打印 即无消息接收

 

点击按钮 第一次点击

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   4   波数据

D/TAG: Flowable创建被观察者 观察者 onComplete方法 

 

点击按钮第二三四五...次点击

无打印 即无消息接收

 

 

 

 

 

 

 

二.控制 被观察者 发送事件的速度

 

<1> 前言

上述可知可以通过观察者的onSubscribe方法中参数Subscription的request(N)方法控制观察者可接收的消息数,继而控制观察者接收事件的速度。那么被观察者的发送事件的速度怎么控制呢?

 

源码分析

 

create操作符创建被观察者 重写 subscribe方法 该方法参数FlowableEmitter<Object> e 点击

public interface FlowableEmitter<T> extends Emitter<T> {

    /**
     * Sets a Disposable on this emitter; any previous Disposable
     * or Cancellation will be unsubscribed/cancelled.
     * @param s the disposable, null is allowed
     */
    void setDisposable(Disposable s);

    /**
     * Sets a Cancellable on this emitter; any previous Disposable
     * or Cancellation will be unsubscribed/cancelled.
     * @param c the cancellable resource, null is allowed
     */
    void setCancellable(Cancellable c);

    /**
     * The current outstanding request amount.
     * <p>This method is thread-safe.
     * @return the current outstanding request amount
     */
    long requested();

    /**
     * Returns true if the downstream cancelled the sequence.
     * <p>This method is thread-safe.
     * @return true if the downstream cancelled the sequence
     */
    boolean isCancelled();

    /**
     * Ensures that calls to onNext, onError and onComplete are properly serialized.
     * @return the serialized FlowableEmitter
     */
    FlowableEmitter<T> serialize();
}

 

可以看到 此参数可以判断是否取消订阅  isCancelled()方法。而request()方法可以获取被观察者中的消息数量。

 

 

<2> 同步订阅 控制被观察者发送消息速度

 

(1) 简介

同步订阅中,被观察者和观察者处在同一线程。被观察者中request方法得到的数等于观察者中Subscription.request()方法中设置的数

 

 

(2) 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        method();
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                long msgNumber = e.requested();
                Log.d("TAG", "Flowable创建被观察者 被观察者 msgNumber----:" + msgNumber);

                if (!e.isCancelled()) {
                    for (int i = 0; i < msgNumber; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                        mSubscription.request(5);//观察者设置可接收五条消息
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

 

(3) 结果

D/TAG: Flowable创建被观察者 被观察者 msgNumber----:5


D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   3   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   4   波数据

D/TAG: Flowable创建被观察者 观察者 onComplete方法 

 

 

(4) 说明

{1} 被观察者的 e.requested();方法具有实时性。即被观察者发送了一条数据 e.requested();方法就会减一。

 

代码 在上基础上改动

long msgNumber = e.requested();
Log.d("TAG", "Flowable创建被观察者 被观察者 msgNumber----:" + msgNumber);

if (!e.isCancelled()) {
    for (int i = 0; i < msgNumber; i++) {
        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
        Log.d("TAG", "Flowable创建被观察者 被观察者 发送了i后e.requested()----:" + e.requested());
    }
    e.onComplete();
}

 

结果

D/TAG: Flowable创建被观察者 被观察者 msgNumber----:5

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据

D/TAG: Flowable创建被观察者 被观察者 发送了i后e.requested()----:4

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 被观察者 发送了i后e.requested()----:3

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 被观察者 发送了i后e.requested()----:2

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   3   波数据

D/TAG: Flowable创建被观察者 被观察者 发送了i后e.requested()----:1

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   4   波数据

D/TAG: Flowable创建被观察者 被观察者 发送了i后e.requested()----:0

D/TAG: Flowable创建被观察者 观察者 onComplete方法 

 

{2} 观察者没有设置可接收事件数量,即无调用Subscription.request()。那么被观察者默认观察者可接收事件数量 = 0,即FlowableEmitter.requested()的返回值 = 0。

 

{3} 可叠加性

 

代码

mSubscription.request(5);//第一次设置 观察者设置可接收五条消息 

mSubscription.request(10);//第二条设置 观察者设置可接收十条消息

 

结果 5+10=15

D/TAG: Flowable创建被观察者 被观察者 msgNumber----:15

 

 

 

 

<3> 异步订阅 控制被观察者发送消息速度

 

(1) 说明

异步订阅中,被观察者和观察者处在不同的线程。所以被观察者 无法通过 FlowableEmitter.requested()知道观察者自身接收事件能力。即 被观察者不能根据 观察者自身接收事件的能力 控制发送事件的速度。

被观察者中request方法得到的数==128,96,0。 和观察者中Subscription.request()方法中设置的数不相等

 

 

(2) 代码

package com.example.mydemo.rxjava;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mydemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        method();
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    public void method() {

        Flowable.create(new FlowableOnSubscribe<Object>() {
            @Override
            public void subscribe(FlowableEmitter<Object> e) throws Exception {
                if (null == e) {
                    return;
                }

                long msgNumber = e.requested();
                Log.d("TAG", "Flowable创建被观察者 被观察者 msgNumber----:" + msgNumber);

                if (!e.isCancelled()) {
                    for (int i = 0; i < msgNumber; i++) {
                        e.onNext("Flowable创建被观察者 被观察者发送第   " + i + "   波数据");
                    }
                    e.onComplete();
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribeOn(Schedulers.io())//被观察者 IO线程
                .observeOn(AndroidSchedulers.mainThread())//观察者 UI线程
                .subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                        mSubscription.request(5);//观察者设置可接收五条消息
                    }

                    @Override
                    public void onNext(Object o) {
                        if (null == o) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 o.toString()----:" + o.toString());
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

 

(3) 结果

D/TAG: Flowable创建被观察者 被观察者 msgNumber----:128


D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   0   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   1   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   2   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   3   波数据

D/TAG: Flowable创建被观察者 观察者 onNext方法 o.toString()----:Flowable创建被观察者 被观察者发送第   4   波数据

即 观察者设置可以接收的消息数是五条,但是被观察者中请求的消息数是128

 

 

 

 

 

 

 

三.Flowable其他操作符使用背压策略

 

<1> 前言

上述的讲解都是使用的Flowable的create操作符创建的被观察者,那么背压策略可以在第二个参数传入。如下。

Flowable.create(new FlowableOnSubscribe<Object>() {
    @Override
    public void subscribe(FlowableEmitter<Object> e) throws Exception {
        if (null == e) {
            return;
        }
 
        if (!e.isCancelled()) {
            e.onNext("Flowable创建被观察者 被观察者发送第1波数据");
            e.onNext("Flowable创建被观察者 被观察者发送第2波数据");
            e.onNext("Flowable创建被观察者 被观察者发送第3波数据");
            e.onComplete();
        }
 
        Log.d("TAG", "Flowable创建被观察者 被观察者 subscribe方法 线程----:" + Thread.currentThread().getName());
    }
}, BackpressureStrategy.LATEST);

 

那么使用其他的操作符呢,比如前节讲的interval操作符。下面讲解。

 

 

 

<2> 代码

package com.wjn.rxdemo.rxjava;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.wjn.rxdemo.R;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;

public class RxJavaActivity extends AppCompatActivity {

    private Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        method();
    }

    /**
     * RxJava Flowable创建被观察者 背压
     */

    private void method() {
        Flowable.interval(1, TimeUnit.MILLISECONDS)
                .onBackpressureBuffer() // 添加背压策略封装好的方法,此处选择Buffer模式,即缓存区大小无限制
                .observeOn(Schedulers.newThread())
                .subscribe(new Subscriber<Long>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        if (null == s) {
                            return;
                        }
                        mSubscription = s;
                        s.request(Long.MAX_VALUE);//观察者设置可接收最多条数的消息
                    }

                    @Override
                    public void onNext(Long aLong) {
                        if (null == aLong) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onNext方法 aLong----:" + aLong);
                        //模拟1秒接收
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (null == t) {
                            return;
                        }
                        Log.d("TAG", "Flowable创建被观察者 观察者 onError方法 t.toString()----:" + t.toString());
                    }

                    @Override
                    public void onComplete() {
                        Log.d("TAG", "Flowable创建被观察者 观察者 onComplete方法 ");
                    }
                });
    }

    /**
     * onDestroy方法 取消订阅
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mSubscription) {
            mSubscription.cancel();
            Log.d("TAG", "退出页面 取消订阅");
        }
    }

}

 

 

<3> 结果

D/TAG: Flowable创建被观察者 观察者 onNext方法 aLong----:0

D/TAG: Flowable创建被观察者 观察者 onNext方法 aLong----:1

D/TAG: Flowable创建被观察者 观察者 onNext方法 aLong----:2

D/TAG: Flowable创建被观察者 观察者 onNext方法 aLong----:3

D/TAG: Flowable创建被观察者 观察者 onNext方法 aLong----:4

D/TAG: Flowable创建被观察者 观察者 onNext方法 aLong----:5

 

 

<4> 关闭页面

D/TAG: 退出页面 取消订阅

 

 

<5> 说明

上述代码中有这样的设置

.onBackpressureBuffer() // 添加背压策略封装好的方法,此处选择Buffer模式,即缓存区大小无限制

那么还有没有其他的设置呢,以及每个设置对应的含义是什么呢。

 

举例含义对create操作符
.onBackpressureBuffer()缓存区满时 将缓存区设置无限大 注意内存溢出BUFFER
.onBackpressureDrop()缓存区满时 事件丢失 保留[0,127]条数据 即 前 128条数据DROP
onBackpressureLatest()缓存区满时 事件丢失 保留[0,127]条数据+超出的最后一条数据

LATEST

 

 

 

 

 

 

 

 

 

 

 

四.总结

<1> RxJava的背压可以使用Flowable创建被观察者来实现。背压的使用大前提是 异步订阅中,观察者和被观察者发送消息的速度或者数量不匹配,一般是被观察者发送的速度太快或者消息太多,观察者来不及处理。

 

<2> 背压一般应用在被观察者和观察者异步订阅时,因为同步订阅正式项目很少使用。(RxJava核心就是异步嘛)。

 

<3> 其实一般使用RxJava实现异步,只要注意在适当的时机取消订阅,防止内存泄漏即可。没必要使用背压。

 

<4> 其实处理被观察者和观察者匹配问题也可以有其他的操作办法,比如使用delay()操作符创建一个延时的被观察者。再比如使用interval操作符创建指定时间的被观察者等等。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值