Android RxJava:Subject使用及示例

RxJava的四种Subjects:PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的理解

Subject:它既是Observable,又是observer。也就是既可以发送事件,也可以接收事件。

Subject将观察者和被观察者结合为一体,是观察者和被观察者的代理。

下面是四个子类PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别:

PublishSubject<Integer> source = PublishSubject.create();  //PublicSubject:接收到订阅之后的所有数据。
// It will get 1, 2, 3, 4 and onComplete
source.subscribe(getFirstObserver()); 
source.onNext(1);
source.onNext(2);
source.onNext(3);
// It will get 4 and onComplete for second observer also.
source.subscribe(getSecondObserver());
source.onNext(4);
source.onComplete();
ReplaySubject<Integer> source = ReplaySubject.create();  //ReplaySubject:接收到所有的数据,包括订阅之前的所有数据和订阅之后的所有数据。
// It will get 1, 2, 3, 4
source.subscribe(getFirstObserver());
source.onNext(1);
source.onNext(2);
source.onNext(3);
source.onNext(4);
source.onComplete();
// It will also get 1, 2, 3, 4 as we have used replay Subject
source.subscribe(getSecondObserver());
BehaviorSubject<Integer> source = BehaviorSubject.create();  //BehaviorSubject:接收到订阅前的最后一条数据和订阅后的所有数据。
// It will get 1, 2, 3, 4 and onComplete
source.subscribe(getFirstObserver());
source.onNext(1);
source.onNext(2);
source.onNext(3);
// It will get 3(last emitted)and 4(subsequent item) and onComplete
source.subscribe(getSecondObserver());
source.onNext(4);
source.onComplete();
AsyncSubject<Integer> source = AsyncSubject.create();  //AsyncSubject:不管在什么位置订阅,都只接接收到最后一条数据
// It will get only 4 and onComplete
source.subscribe(getFirstObserver());
source.onNext(1);
source.onNext(2);
source.onNext(3);
// It will also get only get 4 and onComplete
source.subscribe(getSecondObserver());
source.onNext(4);
source.onComplete();

Subject使用及示例

本文介绍RxJava中Subject的使用。小白同学们看清楚并记好了,这里讲的是Subject,不是Subscribe,不是Subscription,不是subscribeOn,不是OnSubscribe,不是Schedulers,更不是Single,而是Subject

这么多S开头的的单词有没有把你弄糊涂啊,英语好的同学可以略过这段。这里把RxJava中容易和Subject弄混的概念都拿出来介绍一下,还是那句话,看不明白没关系,以后还会讲的!

概念解释
Subject翻译为主题、科目。可以想象成杂志中的板块吧…
Subscribe订阅。可以想象成订阅杂志啊…
OnSubscribe当订阅的时候要做的事情。可以想象为当有用户订阅的时候开始写文章…
subscribeOn做事情所在的线程
Schedulers调度器。上节有讲,用于指定在哪个线程工作,与subscribeOn配套使用
Single单一的输入输出异步任务

RxJava中常见的Subject有4种,分别是AsyncSubject、 BehaviorSubject、 PublishSubject、 ReplaySubject

值得注意的是一定要用Subcect.create()的方式创建并使用,不要用just(T)、from(T)、create(T)创建,否则会导致失效…

值得注意的是我们使用的just()是一种特殊的create(),它不能指定Schedulers。只能在当前线程中运行,而create()可以指定Schedulers实现异步处理。且just()不管是否被subscribe()订阅均会被调用,而create()如果不被订阅是不会被调用的。所以我们通常可以用just()传递简单参数,而用create()处理复杂异步逻辑。

AsyncSubject

简单的说使用AsyncSubject无论输入多少参数,永远只输出最后一个参数。
AS img

// 无论订阅的时候AsyncSubject是否Completed,均可以收到最后一个值的回调
AsyncSubject as = AsyncSubject.create();
as.onNext(1);
as.onNext(2);
as.onNext(3);
// 这里订阅收到3
as.onCompleted();
// 结束后,这里订阅也能收到3
as.subscribe(
        new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                LogHelper.e("S:" + o);// 这里只会输出3
            }
        });

// 不要这样使用Subject
AsyncSubject.just(1, 2, 3).subscribe(
        new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                // 这里会输出1, 2, 3
                LogHelper.e("S:" + o);
            }
        });
// 因为just(T)、from(T)、create(T)会把Subject转换为Obserable

但是如果因为发生了错误而终止,AsyncSubject将不会发射任何数据,只是简单的向前传递这个错误通知。
AS error img

BehaviorSubject

BehaviorSubject会发送离订阅最近的上一个值,没有上一个值的时候会发送默认值。看图
BS img
如果遇到错误会直接中断
BS error img

// 注意订阅时机,以下这个例子收不到回调
BehaviorSubject bs = BehaviorSubject.create(-1);
// 这里订阅回调-1, 1, 2, 3
bs.onNext(1);
// 这里订阅回调1, 2, 3
bs.onNext(2);
// 这里订阅回调2, 3
bs.onNext(3);
// 这里订阅回调3
bs.onCompleted();
// 这里订阅没回调
bs.subscribe(
        new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                LogHelper.e("S:" + o);
            }
        });
PublishSubject

可以说是最正常的Subject,从那里订阅就从那里开始发送数据。
PS img

PublishSubject bs = PublishSubject.create();
// 这里订阅接收1, 2, 3
bs.onNext(1);
// 这里订阅接收2, 3
bs.onNext(2);
// 这里订阅接收3
bs.onNext(3);
bs.onCompleted();
// 这里订阅无接收
bs.subscribe(
        new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                LogHelper.e("S:" + o);
            }
        });
ReplaySubject

无论何时订阅,都会将所有历史订阅内容全部发出。

ReplaySubject bs = ReplaySubject.create();
// 无论何时订阅都会收到1,2,3
bs.onNext(1);
bs.onNext(2);
bs.onNext(3);
bs.onCompleted();
bs.subscribe(
        new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                LogHelper.e("S:" + o);
            }
        });
总结

总的来说Subject没法指定异步线程,更像是EventBus通过订阅来实现事件通知。

参考:https://www.jianshu.com/p/1257c8ba7c0c
https://www.cnblogs.com/yongfengnice/p/10229473.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值