Rxjava2笔记2

笔记1操作符的介绍:Rxjava2的笔记1 --操作符_observable.just传入多参数-CSDN博客

参考视频:https://edu.csdn.net/course/play/10037/213573

基本响应类型

Observable:最基本的响应类型,不支持背压

背压是什么

背压就是上游发送数据的速度很快,下游没有来得及处理,就会累积很多数据;在高并发的时候会发生背压

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("123");
                emitter.onComplete();
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

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

                    @Override
                    public void onError(Throwable e) {

                    }

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

 

Flowable和Observable使用基本类似,Observable不支持背压,Flowable支持背压,使用Flowable的时候,必须调用Subscription的request的方法请求

Flowable.create(new FlowableOnSubscribe<String>() {
            @Override
            public void subscribe(FlowableEmitter<String> emitter) throws Exception {
                emitter.onNext("123");
                emitter.onNext("456");
                emitter.onNext("789");
                emitter.onComplete();
            }
            //背压策略
        }, BackpressureStrategy.DROP)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        //下游可以接受2个数据
                        s.request(2);
                    }

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

                    @Override
                    public void onError(Throwable t) {

                    }

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

Single:只发射一个元素的相应类型,发射onSuccess或者onError方法

 Single.create(new SingleOnSubscribe<String>() {
            @Override
            public void subscribe(SingleEmitter<String> emitter) throws Exception {
                emitter.onSuccess("success");
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

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

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

Completable:仅仅给下游一个信号的响应类型,回调onComplete或者onError

Completable.create(new CompletableOnSubscribe() {
            @Override
            public void subscribe(CompletableEmitter emitter) throws Exception {
                emitter.onComplete();
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new CompletableObserver() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

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

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

Maybe:Single和Completable的结合,信号和数据的结合,但也只能接收到其中的一员

Maybe.create(new MaybeOnSubscribe<String>() {
            @Override
            public void subscribe(MaybeEmitter<String> emitter) throws Exception {
                emitter.onSuccess("success");
                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new MaybeObserver<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

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

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

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

Rxjava的背压策略

背压是什么

背压在高并发中较为常见,在异步场景中,由于数据流的发射速度大于数据流的接收速度,导致数据不能及时接收,从而导致数据流的阻塞,背压所要做的就是主动控制数据流发射的速度.

Rxjava2中使用Flowable用来支持背压,Observable对背压不支持

1.在订阅的时候如果使用FlowableSubscriber,需要通过s.request(Long.MAX_VALUE)去主动请求上游的数据项,遇到背压报错的时候,FlowableSubscriber默认已经将错误try-catch,并通过onError回调,程序并不会崩溃;

2.在订阅的时候如果使用Consumer,那么不需要主动去请求上游数据,默认已经调用了s.request(Long.MAX_VALUE),如果遇到背压报错,且对Throwable的Consumer没有new出来,则程序直接崩溃;

3.背压策略上游的缓存池默认为128

MISSING:表示OnNext对事件没有任何的缓存和丢弃,下游要处理任何溢出,其实可以理解为没有背压,所以超出128的就会异常

 Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 129; i++) {
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.MISSING)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE);
                    }

                    @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() {

                    }
                });

可以看到0-128共129个,超出128了,所以异常,但是因为是Flowable,所以会try-catch住,回调到onError

ERROR:下游无法跟上上游的发射速度时,会抛出异常

Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 129; i++) {
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.ERROR)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE);
                    }

                    @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() {

                    }
                });

无法发出第129个数据 

BUFFER:上游不断的发出onNext请求,直到下游处理完,上游发射的数据项的缓存池是无限大的,程序也不会抛错误,但是由于缓存占用内存,所以可能出现OOM-内存溢出现象

 Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 129; i++) {
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.BUFFER)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE);
                    }

                    @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() {

                    }
                });

可以看到129个数据全部发了出来 

DROP:对于多余的数据会丢弃掉

Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 129; i++) {
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.DROP)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE);
                    }

                    @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() {

                    }
                });

latest:除了128个数据之外,还会把最后一个数据也放入缓存池中

 Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 130; i++) {
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.LATEST)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<Integer>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(Long.MAX_VALUE);
                    }

                    @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() {

                    }
                });

 为了明显,我把数据发射了130个,所以最后一个也

实战1 - 模拟发送验证码

这里面的操作符有不会的可以去看笔记1

 private void initRxjava1() {
        mButton = findViewById(R.id.button);
        mButton.setText("点击发送验证码");
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                verify();
            }
        });
    }

    @SuppressLint("CheckResult")
    private void verify() {
        final int count = 3; //倒计时3秒
        Observable.interval(0,1, TimeUnit.SECONDS)
                .take(count+1) //0,1,2,3
                .map(new Function<Long, Long>() {
                    @Override
                    public Long apply(Long aLong) throws Exception {
                        return count - aLong; //转换为3,2,1,0
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                //监听生命周期
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) throws Exception {
                        mButton.setEnabled(false);
                    }
                })
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //在0秒的时候会调用到complete,所以没有显示剩余0秒
                        mButton.setText("剩余" + aLong+"秒");
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {

                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        //onComplete事件
                        mButton.setEnabled(true);
                        mButton.setText("点击发送验证码");
                    }
                });
    }

运行结果:

实战2.防止用户多次点击

throttleFirst这个属性

private void initView() {
        mButton = findViewById(R.id.button);
        query(mButton);
    }

    public void query(View view) {
        RxUtils.click(view, 2)
                .subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

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

                    @Override
                    public void onError(Throwable e) {

                    }

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

    static class RxUtils {
        //非静态内部类不能有静态方法
        public static Observable<Object> click(final View view, long seconds) {
            return new ViewClickObservable(view)
                     //2秒内只接受第一次点击
                    .throttleFirst(2, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnDispose(new Action() {
                        @Override
                        public void run() throws Exception {
                            if (view !=null){
                                view.setOnClickListener(null);
                            }
                        }
                    });
        }
    }

    static class ViewClickObservable extends Observable<Object> {
        private View mView;

        public ViewClickObservable(View view) {
            this.mView = view;
        }

        @Override
        protected void subscribeActual(Observer<? super Object> observer) {
            if (mView != null) {
                mView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        observer.onNext(mView);
                    }
                });
            }
        }
    }

第二种写法,前面是对Observable的重写,这个是对ObservableOnSubscribe的重写

@SuppressLint("CheckResult")
    private void initView() {
        mButton = findViewById(R.id.button);
        query(mButton);
    }

    public void query(View view) {
        RxUtils.click(view, 2)
                .subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

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

                    @Override
                    public void onError(Throwable e) {

                    }

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

    static class ViewClickObservableOnSubscribe implements ObservableOnSubscribe<Object> {
        ObservableEmitter<Object> mEmitter;

        public ObservableEmitter<Object> getEmitter() {
            return mEmitter;
        }

        @Override
        public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
            mEmitter = emitter;
        }
    }

    static class RxUtils {
        //非静态内部类不能有静态方法
        public static Observable<Object> click(final View view, long seconds) {
            ViewClickObservableOnSubscribe viewClickObservableOnSubscribe = new ViewClickObservableOnSubscribe();
            if (view !=null){
                view.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        ObservableEmitter<Object> emitter = viewClickObservableOnSubscribe.getEmitter();
                        emitter.onNext(view);
                    }
                });
            }
            return Observable.create(viewClickObservableOnSubscribe)
                    .throttleFirst(2, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnDispose(new Action() {
                        @Override
                        public void run() throws Exception {
                            if (view != null) {
                                view.setOnClickListener(null);
                            }
                        }
                    });
        }
    }

运行效果:在2秒内点击多次,但只接受第一次的点击

实战3 : 模拟会员信息的合并

需求:获取列表中的会员信息,当本地有缓存时,就从本地获取信息,否则就从网络获取

public static class Vip {
}

 //用来本地缓存会员信息的map
private HashMap<Long, Vip> mVipCache = new HashMap<>();
 //获取列表的方法
    public Observable<HashMap<Long, Vip>> getVipList(List<Long> uids) {
        List<Long> vipRequest = new ArrayList<>();
        HashMap<Long, Vip> vipLocal = new HashMap<>();

        for (Long uid : uids) {
            if (mVipCache.containsKey(uid)) {
                Log.e(TAG, "从本地获取数据 " + uid + "用户");
                vipLocal.put(uid, mVipCache.get(uid));
            } else {
                Log.e(TAG, "从网络获取数据 " + uid + "用户");
                vipRequest.add(uid);
            }
        }
        if (vipRequest.isEmpty()) {
            return Observable.just(vipLocal);
        }
        return Observable.merge(Observable.just(vipLocal), getVipFromWeb(vipRequest));
    }
    
    //从网络获取列表的方法
    public Observable<HashMap<Long, Vip>> getVipFromWeb(List<Long> uids) {
        HashMap<Long, Vip> vipList = new HashMap<>();
        for (Long uid : uids) {
            Vip vip1 = new Vip();
            vipList.put(uid, vip1);
        }
        //缓存到本地
        mVipCache.putAll(vipList);

        return Observable.just(vipList);
    }
public void initData() {
        List<Long> uids = new ArrayList<>();
        Log.e(TAG, "第一次查询: ");
        uids.add(1L);
        uids.add(2L);
        getVipList(uids);
        uids.clear();

        Log.e(TAG, "第二次查询: ");
        uids.add(1L);
        uids.add(2L);
        uids.add(3L);
        uids.add(4L);
        getVipList(uids);
        uids.clear();

        Log.e(TAG, "第三次查询 ");
        uids.add(1L);
        uids.add(2L);
        uids.add(3L);
        uids.add(4L);
        mVipCache.clear();
        getVipList(uids);
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值