一、Relay
relay 英 [ˈriːleɪ] 美 [ˈriːleɪ]
v. 接转,转送,转发(信息、消息等); 播放,转播(电视或广播讯号);
n. 接力赛; 接班的人(或动物); 轮换者; 中继设备
Rxrelay:既是一个Observable 也是 一个Consumer的RxJava。
基本上可以当做是一个除了无法调用onComplete或onError之外的Subject。
使用它的好处就是不必担心事件在onComplete或者onError后终止事件订阅关系,
它允许将非Rx API连接到Rx,而不用担心意外触发终端状态(onComplete或者onError)。
package com.jakewharton.rxrelay2;
/**
* Represents a Consumer and an Observable at the same time, allowing
* multicasting events from a single source to multiple child Observers.
* <p>All methods except {@link #accept} are thread-safe.
* Use {@link #toSerialized()} to make it thread-safe as well.
*
* @param <T> the item value type
*/
// 同时代表一个消费者和一个可观察对象,
// 从而允许将事件从单个源多播到多个子观察者。
// 除{@link #accept}之外的所有方法都是线程安全的。
// 使用{@link #toSerialized()}使其也成为线程安全的。
//
public abstract class Relay<T> extends Observable<T> implements Consumer<T> {
/** {@inheritDoc} */
@Override public abstract void accept(@NonNull T value);
// Redeclare without checked exception.
/**
* Returns true if the subject has any Observers.
* <p>The method is thread-safe.
*/
public abstract boolean hasObservers();
/**
* Wraps this Relay and serializes the calls to {@link #accept}, making it thread-safe.
* <p>The method is thread-safe.
*/
@NonNull
@CheckReturnValue
public final Relay<T> toSerialized() {
if (this instanceof SerializedRelay) {
return this;
}
return new SerializedRelay<T>(this);
}
}
PublishRelay:只接受订阅后的事件
PublishRelay<Object> relay = PublishRelay.create();
// observer1 will receive all events
relay.subscribe(observer1);//一经注册,后续都可接收
relay.accept("one");
relay.accept("two");
// observer2 will only receive "three"
relay.subscribe(observer2);
relay.accept("three");
ReplayRelay:接受订阅前和订阅后的所有事件
ReplayRelay<Object> relay = new ReplayRelay<>();
relay.accept("one");
relay.accept("two");
relay.accept("three");
// both of the following will get the values from above
relay.subscribe(observer1);//先发送,再注册:也可接收到
relay.subscribe(observer2);
BehaviorRelay:他会接收订阅之前的最后一个事件和订阅之后的事件
// observer will receive all events.
BehaviorRelay<Object> subject = BehaviorRelay.create("default");
subject.subscribe(observer);
subject.accept("one");
subject.accept("two");
subject.accept("three");
// observer will receive the "one", "two" and "three" events, but not "zero"
BehaviorRelay<Object> subject = BehaviorRelay.create("default");
subject.accept("zero");
subject.accept("one");
subject.subscribe(observer);
subject.accept("two");
subject.accept("three");
二、Subject
package io.reactivex.subjects;
/**
* Represents an {@link Observer} and an {@link Observable} at the same time, allowing
* multicasting events from a single source to multiple child {@code Observer}s.
* <p>
* All methods except the {@link #onSubscribe(io.reactivex.disposables.Disposable)},
* {@link #onNext(Object)},
* {@link #onError(Throwable)} and {@link #onComplete()} are thread-safe.
* Use {@link #toSerialized()} to make these methods thread-safe as well.
*
*/
//同时代表一个{@link Observer}和{@link Observable},
//从而允许将事件从单个源多播到多个子{@code Observer}。
//所有除了
//{@link #onSubscribe(io.reactivex.disposables.Disposable)},
//{@link #onNext(Object)},
//{@link #onError(Throwable)}和{@link# onComplete()}是线程安全的。
//使用{@link #toSerialized()}也可以使这些方法成为线程安全的。
//
public abstract class Subject<T> extends Observable<T> implements Observer<T> {
/**
* Returns true if the subject has any Observers.
* <p>The method is thread-safe.
* @return true if the subject has any Observers
*/
public abstract boolean hasObservers();
/**
* Returns true if the subject has reached a terminal state through an error event.
* <p>The method is thread-safe.
* @return true if the subject has reached a terminal state through an error event
* @see #getThrowable()
* @see #hasComplete()
*/
public abstract boolean hasThrowable();
/**
* Returns true if the subject has reached a terminal state through a complete event.
* <p>The method is thread-safe.
* @return true if the subject has reached a terminal state through a complete event
* @see #hasThrowable()
*/
public abstract boolean hasComplete();
/**
* Returns the error that caused the Subject to terminate or null if the Subject
* hasn't terminated yet.
* <p>The method is thread-safe.
* @return the error that caused the Subject to terminate or null if the Subject
* hasn't terminated yet
*/
@Nullable
public abstract Throwable getThrowable();
/**
* Wraps this Subject and serializes the calls to the onSubscribe, onNext, onError and
* onComplete methods, making them thread-safe.
* <p>The method is thread-safe.
* @return the wrapped and serialized subject
*/
@NonNull
public final Subject<T> toSerialized() {
if (this instanceof SerializedSubject) {
return this;
}
return new SerializedSubject<T>(this);
}
}
PublishSubject :只接受订阅后的事件
PublishSubject<Object> subject = PublishSubject.create();
// observer1 will receive all onNext and onComplete events
subject.subscribe(observer1);
subject.onNext("one");
subject.onNext("two");
// observer2 will only receive "three" and onComplete
subject.subscribe(observer2);
subject.onNext("three");
subject.onComplete();
// late Observers only receive the terminal event
subject.test().assertEmpty();
ReplaySubject :接受订阅前和订阅后的所有事件
ReplaySubject<Object> subject = ReplaySubject.create();
subject.onNext("one");
subject.onNext("two");
subject.onNext("three");
subject.onComplete();
// both of the following will get the onNext/onComplete calls from above
subject.subscribe(observer1);//先发送,再注册,也能收到
subject.subscribe(observer2);
BehaviorSubject :他会接收订阅之前的最后一个事件和订阅之后的事件。
// observer will receive all 4 events (including "default").
BehaviorSubject<Object> subject = BehaviorSubject.createDefault("default");
subject.subscribe(observer);//订阅
subject.onNext("one");
subject.onNext("two");
subject.onNext("three");
// observer will receive the "one", "two" and "three" events, but not "zero"
BehaviorSubject<Object> subject = BehaviorSubject.create();
subject.onNext("zero");
subject.onNext("one");
subject.subscribe(observer);//订阅
subject.onNext("two");
subject.onNext("three");
// observer will receive only onComplete
BehaviorSubject<Object> subject = BehaviorSubject.create();
subject.onNext("zero");
subject.onNext("one");
subject.onComplete();
subject.subscribe(observer);//订阅
// observer will receive only onError
BehaviorSubject<Object> subject = BehaviorSubject.create();
subject.onNext("zero");
subject.onNext("one");
subject.onError(new RuntimeException("error"));
subject.subscribe(observer);//订阅
subject.accept("three");
SerializedSubject :
序列化对Observer方法的调用。 所有其他Observable和Subject方法在设计上都是线程安全的。
三、 RxRelay 与 Subject区别:
public abstract class Subject<T> extends Observable<T> implements Observer<T> {...}
public abstract class Relay<T> extends Observable<T> implements Consumer<T> {...}
由上图可见 RxRelay 与 Subject区别 即是 Consumer和Observer区别:
四、 简单的 RxBus 与 Subject
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;
public class RxBus {
private static volatile Subject<Object> instance;
private RxBus() {
instance = PublishSubject.create().toSerialized();
}
private static class Holder {
private static final RxBus BUS = new RxBus();
}
public static RxBus getDefault() {
return Holder.BUS;
}
public void post(Object obj) {
instance.onNext(obj);
}
public <T> Observable<T> toObservable(Class<T> tClass) {
return instance.ofType(tClass);
}
public Observable<Object> toObservable() {
return instance;
}
public boolean hasObservers() {
return instance.hasObservers();
}
}
测试:
public void test() {
//发送
RxBus.getDefault().post(new String("111"));
//接收
CompositeDisposable compositeDisposable = new CompositeDisposable();
Disposable disposable = RxBus.getDefault()
.toObservable(String.class)
.toFlowable(BackpressureStrategy.BUFFER)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
}
});
compositeDisposable.add(disposable);
if (!compositeDisposable.isDisposed()) {//避免内存泄漏
compositeDisposable.dispose();
}
}