Rxjava2.0中的 Subject

Rxjava Subject

目录

  • 与Rxjava1.0相比
  • 继承关系
  • doc解释
  • 8种Subject
  • Subject作为观察者使用
  • 总结

与Rxjava1.0相比

  1. 其实2.0变化并不大,本质上没什么变化,只是使用方式上传入的参数有所改变,大家都知道2.0使用Consumer取代了Action1-9(保留了Action,但是回调方法名字也改了)。
  2. 包名名变为:io.reactivex.subjects
  3. 去掉掉了SerializedSubject,新增了CompletableSubject、MaybeSubject、SingleSubject

2.继承关系

继承关系:


Class Subject<T>
    java.lang.Object
        io.reactivex.Observable<T>
            io.reactivex.subjects.Subject<T>

声明:

public abstract class Subject<T>
extends Observable<T>
implements Observer<T>

Subject继承Observable,并实现Observer接口,表明Subject既可以作为被观察者,又可作为观察者

3.Subject doc解释

Subject可以看成是一个桥梁或者代理,在某些ReactiveX实现中(如RxJava),它同时充当了Observer和Observable的角色。因为它是一个Observer,它可以订阅一个或多个Observable;又因为它是一个Observable,它可以转发它收到(Observe)的数据,也可以发射新的数据。

4.八种Subject

  • AsyncSubject

AysncSubject只在原始的Observable完成后,发送最后一个数据给Observer,如果Observable发射过程中出现错误终止,AysncSubject将不发送任何数据。

这里写图片描述

AsyncSubject aSubject = AsyncSubject.create();

        aSubject.onNext("1");
        aSubject.onNext("2");

        aSubject.subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println("1-AsyncSubject:"+s);
            }
        }) ;
        aSubject.onNext("3");
        aSubject.onNext("4");
        aSubject.onNext("5");
        //必须调用,否则Subject不知道什么时候发射完,Observer接收不到数据
        aSubject.onComplete();  

        aSubject.subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println("2-AsyncSubject:"+s);
            }
        }) ;

执行结果:

这里写图片描述

特别注意:

有童鞋肯定会想,既然Subject可以作为Observable,那么通过操作符创建Subject:

AsyncSubject<String> subject = (AsyncSubject<String>Async)Subject.just("1","2","3") ;
Asyncsubject.subscribe(new Consumer(String){
    @Override
    public void accept(@NonNull String s) throws Exception{
        System.Out.prinln(s) ;
    }
}) ;

代码写的很溜,然而错的也很溜!Subject.just()调用的是父类方法,创建的Observable,通过这种方式获取的Subject属于下转型,会报错。所以使用Subject的时候不要使用Observable的操作符实例化Subject,后面介绍的4种Subject依然如此,谨记。

  • BehaviorSubject

发射Observable最近的数据,如果Observable还没有开始发射数据,则发射BehaviorSubject的默认数据,原理图如下:

这里写图片描述

用法
Observable未发送数据之前订阅:会先收到默认值,实际应用中可以利用接收默认值的方式做一些初始化或准备工作

private void rxJavaBebaviorSubject(){
        BehaviorSubject bSubject = BehaviorSubject.createDefault("Default-Value") ;
        bSubject.subscribe(getObserver()) ;
        bSubject.onNext("one");
        bSubject.onNext("two");
        bSubject.onNext("three");
        bSubject.onNext("four");
    }

    private Consumer<String> getObserver(){
        return new Consumer<String>(){
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println("BehaviorSubject:"+s);
            }
        } ;
    }

运行结果:
这里写图片描述
如果将上述代码中的订阅换下位置:

        bSubject.onNext("one");
        bSubject.onNext("two");
        bSubject.subscribe(getObserver()) ;
        bSubject.onNext("three");
        bSubject.onNext("four");

Observer将只会收到:two、three、four,即:BehaviorSubject只发送订阅之前最近的和订阅之后的数据源


  • PublishSubject

观察者只能接收到订阅之后PublishSubject发射的数据源
这里写图片描述

private Consumer<String> getObserver(final String tag){
        return new Consumer<String>(){
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println(tag+s);
            }
        } ;
    }

    private void rxJavaPublishSubject(){
        PublishSubject<String> pSubject = PublishSubject.create() ;
        pSubject.subscribe(getObserver("Observer-1:")) ;
        pSubject.onNext("A");
        pSubject.onNext("B");
        pSubject.subscribe(getObserver("Observer-2:")) ;
        pSubject.onNext("C");
        pSubject.onNext("D");
    }

执行结果:
这里写图片描述
结果很明显,不需要再做解释。


  • ReplaySubject

无论Observer什么时候订阅,ReplaySubject都会将所有数据发送给订阅观察者Observer
这里写图片描述

private void RxJavaReplaySubject(){
        ReplaySubject<String> rSubject = ReplaySubject.create() ;
        rSubject.onNext("one");
        rSubject.onNext("two");
        rSubject.subscribe(getObserver("Observer-1:")) ;
        rSubject.onNext("three");
        rSubject.onNext("four");
        rSubject.onComplete();
        rSubject.subscribe(getObserver("Observer-2:")) ;
    }

执行结果 :
这里写图片描述
这里不得不说一句,ReplaySubject发送数据是有顺序的,每当有订阅者出现,ReplaySubject会想将已发送的数据重新发送一遍给新订阅者,才会继续发送之后的数据。


  • CompletableSubject

只发送Observer发射完毕数据,即:只发送onCompelted()

CompletableSubject cSubject = CompletableSubject.create() ;
        cSubject.subscribe(new Action() {
            @Override
            public void run() throws Exception {
                System.out.println("CompletableSubject执行完毕");
            }
        }) ;
        cSubject.onComplete();

执行结果:
这里写图片描述


  • MaybeSubject

MaybeSubject所有方法都是线程安全的。主要用于发送一个结果数据,主要方法onSuccess(),多次调用无效。一般用于验证某个结果。

private void rxJavaMabeSubject(){
        MaybeSubject<Boolean> mSubject = MaybeSubject.create() ;
        mSubject.subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(@NonNull Boolean b) throws Exception {
                System.out.println("登录状态:"+b);
            }
        }) ;
        mSubject.onSuccess(isLogin());
        mSubject.onComplete();

    }

    private boolean isLogin(){
        //..一些验证操作
        return true ;
    }

执行结果:
这里写图片描述


  • SingleSubject

其实,SingleSubject和MaybeSubject区别不大,MaybeSubject提供了z状态方法,比如:onComplete()和onErrorComplete(),而SingleSubject没有这些方法,更是印证了Single这个名字,这里就不多说,用法和MaybeSubject一样,直接上代码:

SingleSubject<String> sSubject = SingleSubject.create() ;
        sSubject.subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println("Observable-one:"+s);
            }
        }) ;
        sSubject.onSuccess("success...");


  • UnicastSubject

UnicastSubject只能有一个观察者订阅,如果有多个观察者订阅,程序会报错。
这里写图片描述

UnicastSubject<String> uSubject = UnicastSubject.create() ;
        uSubject.onNext("1");
        uSubject.onNext("2");
        uSubject.subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println("Observer-1:"+s);
            }
        }) ;
        uSubject.onNext("3");
        uSubject.onNext("4");
        uSubject.onComplete();

        //即使UnicastSubject发射完了数据,在订阅其他Observer也不行
        /*uSubject.subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                System.out.println("Observer-2:"+s);
            }
        }) ;*/

5.Subject作为观察者使用

既然Subject实现了Observer接口,那么它就是Observer的子类,可以作为观察者使用,废话不多说,直接上代码:

Subject<String> subject = new Subject<String>(){

            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull String s) {
                System.out.println("subject-oberver:"+s);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                System.err.println("onError...");
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete...");
            }

            @Override
            protected void subscribeActual(Observer<? super String> observer) {

            }

            @Override
            public boolean hasObservers() {
                return false;
            }

            @Override
            public boolean hasThrowable() {
                return false;
            }

            @Override
            public boolean hasComplete() {
                return false;
            }

            @Override
            public Throwable getThrowable() {
                return null;
            }
        } ;

        Observable.just("1","2","3")
                .subscribe(subject) ;

6.总结

Subject既可作Observable又可作Observer,其实从官方提供的子类就能清楚,Subject作为Observable的时候偏多,个人感觉Subject并没有多么出彩的地方,其几个子类实现的功能,Rxjava2.0中的几个Observable也能实现,具体使用还是看个人,能更灵活的使用Rxjava。也是边学编写博客,学习的同时做个记录,如果如有什么不对或不足地方,望个位能指点一下,同学习共同进步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值