Rxjava中的Subject / Precessor

在Rxjava中Subject / Processor 是一种特殊的存在,它既是Observable又是Observer,

rxjava官网中给出的解释是可以将Subject / Processor看成是一个桥梁或者是代理.

Subject常见类型有:

        AsyncSubject ,  BehaviorSubject ,  ReplaySubject,  PublishSubject

Subject发射行为
AsyncSubject不论什么时候订阅只发射最后一个数据而且必须要调用onComplete()才会开始发射数据
BehaviorSubject发送订阅之前发射的最后一个数据(如果没有可以预定义一个默认的数据)和订阅之后的全部数据
ReplaySubject不论订阅发生在什么时候,都发射全部数据,可以自定义接收订阅之前的数据的数量和有效时间
PublishSubject发射订阅之后的全部数据

1.AsyncSubject                                        

 RxView.clicks(findViewById(R.id.btn_asyncsubject)).subscribe(new Consumer<Object>() {
            @Override
            public void accept(@NonNull Object o) throws Exception {
                //Subject中的AsyncSubject
                //对于AsyncSubject 观察者Observer会接收AsyncSubject的onComplete()事件之前的最后一个数据
                AsyncSubject<String> as = AsyncSubject.create();
             
                as.onNext("as-----1  thread : " + Thread.currentThread().getName());
                as.onNext("as-----2  thread : " + Thread.currentThread().getName());
                as.onNext("as-----3  thread : " + Thread.currentThread().getName());
                //注意:AsyncSubject必须要调用onComplete()才会开始发送数据否则观察者是不会接收到任何数据的
//                as.onComplete();

                as/*.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())*/
                        .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d(TAG,"onSubscribe : " + d.isDisposed() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.d(TAG,"onNext : " + s +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG,"onError : " + e.getMessage() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG,"onComplete :  thread : " + Thread.currentThread().getName());
                    }
                });

                as.onNext("as--------4");
                as.onNext("as---------5");
                
                //改一下代码将onComplete()方法最后 我们发现放在中间时接收的是as---3事件
                //而放在最后则是接收的是as-----5事件
                as.onComplete();
                
            }
        });

打印结果:

    

2.BehaviorSubject

RxView.clicks(findViewById(R.id.btn_behaviorsubject)).subscribe(new Consumer<Object>() {
            @Override
            public void accept(@NonNull Object o) throws Exception {
                //Subject之BehaviorSubject
                //BehaviorSubject的特性是会接收它被订阅(subscribe)之前的发射的最后一个数据以及还会接收被订阅(subscribe)之后发射的所有数据
                //对于BehaviorSubject来说如果被订阅之前没有发射任何数据我们可以通过createDefault(T)方法设置一个默认
                //数据那样即使在被订阅(subscribe)之前没有发射任何数据也会接收到这条默认的数据
                
//                BehaviorSubject<Integer> bs = BehaviorSubject.create();
                //创建BehaviorSubject时设置一个被订阅前如果没有发射数据时接收的默认数据
                BehaviorSubject<Integer> bs = BehaviorSubject.createDefault(666);

                bs.onNext(1);
                bs.onNext(2);
                bs.onNext(3);


                bs.map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
//                        Log.d(TAG,"map : thread " + Thread.currentThread().getName());
                        return String.valueOf(integer * 10);
                    }
                }) .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d(TAG,"onSubscribe : " + d.isDisposed() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.d(TAG,"onNext : " + s +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG,"onError : " + e.getMessage() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG,"onComplete :  thread : " + Thread.currentThread().getName());
                    }
                });

                bs.onNext(4);
                bs.onNext(5);
                //对于BehaviorSubject而言不管有没有调用onComplete()方法都会开始发送数据
//                bs.onComplete();

                bs.subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer s) throws Exception {
                        Log.d(TAG,"accept : " + s +  " thread : " + Thread.currentThread().getName());
                    }
                });

                bs.onNext(6);
                bs.onNext(7);
                
            }
        });

打印结果:

      

3.ReplaySubject

RxView.clicks(findViewById(R.id.btn_replaysubject)).subscribe(new Consumer<Object>() {
            @Override
            public void accept(@NonNull Object o) throws Exception {
                //Subject之ReplaySubject
                //ReplaySubject会发射所有来自源Observable的数据给观察者,无论他们是什么时候订阅的
//                ReplaySubject<Integer> rs = ReplaySubject.create();
                //通过createWithSize可以指定缓存在订阅subscribe之前的几条数据 这个和BehaviorSubject有点像
//                ReplaySubject<Integer> rs = ReplaySubject.createWithSize(2);
                //也可以指定缓存数据的有效时间
//                ReplaySubject<Integer> rs = ReplaySubject.createWithTime(10, TimeUnit.SECONDS, Schedulers.io());
                //还可以指定缓存数据的数量和有效时间
                ReplaySubject<Integer> rs = ReplaySubject.createWithTimeAndSize(10, TimeUnit.SECONDS, Schedulers.io(),2);

                rs.onNext(1);
                rs.onNext(2);
                rs.onNext(3);

                rs.map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return String.valueOf(integer * 10);
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d(TAG,"onSubscribe : " + d.isDisposed() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.d(TAG,"onNext : " + s +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG,"onError : " + e.getMessage() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG,"onComplete :  thread : " + Thread.currentThread().getName());
                    }
                });

                rs.onNext(4);
                rs.onNext(5);
                rs.onComplete();
            }
        });

打印结果:

    

4.PublishSubject

RxView.clicks(findViewById(R.id.btn_publishsubject)).subscribe(new Consumer<Object>() {
            @Override
            public void accept(@NonNull Object o) throws Exception {
                //Subject之PublishSubject
                //PublishSubject的特点是它的订阅者Observer会接收它在被订阅之后发射的所有的数据
                PublishSubject<Integer> ps = PublishSubject.create();

                ps.onNext(1);
                ps.onNext(2);
                ps.onNext(3);
//                ps.onComplete();

                ps.map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return String.valueOf(integer * 2);
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d(TAG,"onSubscribe : " + d.isDisposed() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.d(TAG,"onNext : " + s +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG,"onError : " + e.getMessage() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG,"onComplete :  thread : " + Thread.currentThread().getName());
                    }
                });

                ps.onNext(4);
                ps.onNext(5);
                ps.onComplete();
            }
        });

打印结果:

    

5.Subject的事件丢失问题

RxView.clicks(findViewById(R.id.btn_subjectmissdata)).subscribe(new Consumer<Object>() {
            @Override
            public void accept(@NonNull Object o) throws Exception {
                //Subject错过事件的问题
                PublishSubject<Integer> ps = PublishSubject.create();

                ps.onNext(1);
                ps.onNext(2);

                ps.map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        Log.d(TAG,"map : " + Thread.currentThread().getName());
                        return String.valueOf(integer);
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d(TAG,"onSubscribe : " + d.isDisposed() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(@NonNull String s) {
                        Log.d(TAG,"onNext : " + s +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG,"onError : " + e.getMessage() +  " thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG,"onComplete :  thread : " + Thread.currentThread().getName());
                    }
                });

                ps.onNext(3);
                ps.onNext(4);
                for (int i = 0; i < 10000; i++) {
                    ps.onNext(i);
                }
                ps.onComplete();

                //这种情况可以使用Observable.create()进行替代
              /*  Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
                        for (int i = 0; i < 10000; i++) {
                            e.onNext(i);
                        }
                        e.onComplete();
                    }
                }).map(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return String.valueOf(integer);
                    }
                }).subscribeOn(Schedulers.io())
                        .subscribe(new Observer<String>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {
                                Log.d(TAG,"onSubscribe : " + d.isDisposed() +  " thread : " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onNext(@NonNull String s) {
                                Log.d(TAG,"onNext : " + s +  " thread : " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {
                                Log.d(TAG,"onError : " + e.getMessage() +  " thread : " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onComplete() {
                                Log.d(TAG,"onComplete :  thread : " + Thread.currentThread().getName());
                            }
                        });
*/
            }
        });

打印结果:

                   将发射数据的线程切换到io线程                                                                   发射和订阅数据都在主线程

通过打印结果可以看出当我们通过subscribeOn()将PublishSubject发射数据的线程指定到了io线程以后会有一段时间订阅者

Observer没有接收到PublishSubject发射过来的数据导致数据丢失

这主要时因为当我们将发射数据的线程从主线程切换到io线程时io线程是需要进行初始化的,当我们在main主线程进行

数据的发送,而数据从主线程转发到io线程的过程中由于io线程在初始化

还没有起来就导致这部分数据被丢弃了所以就会看到有部分的数据没有打印出来

出现这种问题我们可以使用Observable来代替Subject进行操作,它允许为每个订阅者精确控制事件的发送

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值