Rxjava Subject
目录
- 与Rxjava1.0相比
- 继承关系
- doc解释
- 8种Subject
- Subject作为观察者使用
- 总结
与Rxjava1.0相比
- 其实2.0变化并不大,本质上没什么变化,只是使用方式上传入的参数有所改变,大家都知道2.0使用Consumer取代了Action1-9(保留了Action,但是回调方法名字也改了)。
- 包名名变为:io.reactivex.subjects
- 去掉掉了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。也是边学编写博客,学习的同时做个记录,如果如有什么不对或不足地方,望个位能指点一下,同学习共同进步。