RxRelay源碼解析:
Relays 是既是Observable也是Consumer的RxJava 類型,由於沒有onComplete 或 onError,所以發生異常時不會觸發下游的終止狀態,不會拋出異常。
//接收訂閱之後數據
Relay relay = PublishRelay.create().toSerialized();
//接受訂閱之前一個和之後數據
Relay relay = BehaviorRelay.createDefault("Hello World");
//不管何時訂閱,發送所有數據
Relay relay = ReplayRelay.create(5).toSerialized();
/**
* 隊列,用於存儲帶發射的值
*/
class AppendOnlyLinkedArrayList<T> {
private final int capacity; //容量
private final Object[] head; //用於存放值
private Object[] tail;
private int offset; //數組指針
/**
* 指定容量,初始化數組爲容量大小
*/
AppendOnlyLinkedArrayList(int capacity) {
this.capacity = capacity;
this.head = new Object[capacity + 1];
this.tail = head;
}
/**
* 向隊列插入值
*/
void add(T value) {
final int c = capacity;
int o = offset;
//若容量滿了,創建新數組tail,新數組開始位置指向head末尾,向新數組tail[0]插入值
if (o == c) {
Object[] next = new Object[c + 1];
tail[c] = next;
tail = next;
o = 0;
}
//容量未滿,按偏移量插入值
tail[o] = value;
offset = o + 1;
}
/**
* 自定義條件
*/
public interface NonThrowingPredicate<T> extends Predicate<T> {
@Override
boolean test(T t);
}
/**
* 便利隊列中所有數組,遇到空或返回條件爲真退出
*/
@SuppressWarnings("unchecked")
void forEachWhile(NonThrowingPredicate<? super T> consumer) {
Object[] a = head;
final int c = capacity;
while (a != null) {
for (int i = 0; i < c; i++) {
Object o = a[i];
if (o == null) {
break;
}
if (consumer.test((T)o)) {
break;
}
}
//若數組便利完成,便利下一個數組,a[c]指向下一個數組開頭
a = (Object[])a[c];
}
}
/**
* 遍歷隊列中所有數組,回掉值給Relay的accept方法,遇到空值則退出
* @param observer
* @return
*/
@SuppressWarnings("unchecked")
boolean accept(Relay<? super T> observer) {
Object[] a = head;
final int c = capacity;
while (a != null) {
for (int i = 0; i < c; i++) {
Object o = a[i];
if (o == null) {
break;
}
//回掉值給Relay的accept方法
observer.accept((T) o);
}
a = (Object[])a[c];
}
return false;
}
}
public abstract class Relay<T> extends Observable<T> implements Consumer<T> {
/** 接受數據 */
@Override public abstract void accept(T value); // Redeclare without checked exception.
public abstract boolean hasObservers();
/** 封裝Relay並序列化調用 */
@NonNull
@CheckReturnValue
public final Relay<T> toSerialized() {
if (this instanceof SerializedRelay) {
return this;
}
return new SerializedRelay<T>(this);
}
}
/**
* 序列化Relay,封裝一次Relay
*/
public class SerializedRelay<T> extends Relay<T> {
private final Relay<T> actual;
//表示發射正在進行,由這個控制
private boolean emitting;
//隊列
private AppendOnlyLinkedArrayList<T> queue;
SerializedRelay(final Relay<T> actual) {
this.actual = actual;
}
/**
* 形成訂閱
*/
@Override
protected void subscribeActual(Observer<? super T> observer) {
actual.subscribe(observer);
}
/**
* 接受來自隊列的值
*/
@Override
public void accept(T value) {
synchronized (this) {
//正在發射狀態,就先添加值到隊列
if (emitting) {
AppendOnlyLinkedArrayList<T> q = queue;
if (q == null) {
q = new AppendOnlyLinkedArrayList<T>(4);
queue = q;
}
q.add(value); //添加到隊列
return;
}
emitting = true;
}
//未在發射狀態,直接回掉值給Relay的accept方法
actual.accept(value);
emitLoop();
}
/** 遍歷隊列,回掉值給Relay的accept方法 */
private void emitLoop() {
for (;;) {
AppendOnlyLinkedArrayList<T> q;
synchronized (this) {
q = queue;
//爲空說明已發送完成
if (q == null) {
emitting = false;
return;
}
queue = null;
}
//遍歷隊列q中所有數組,回掉值給Relay的accept方法,遇到空值則退出
q.accept(actual);
}
}
@Override
public boolean hasObservers() {
return actual.hasObservers();
}
}
/**
* 發送訂閱之後數據
* @param <T>
*/
public class PublishRelay<T> extends Relay<T> {
//一個空的訂閱者數組,以避免一直分配它
@SuppressWarnings("rawtypes")
static final PublishDisposable[] EMPTY = new PublishDisposable[0];
//原子引用,使得多線程操作的是同一個對象
final AtomicReference<PublishDisposable<T>[]> subscribers;
/**
* 生成一個原子引用的訂閱者數組EMPTY
*/
@CheckReturnValue
@NonNull
public static <T> PublishRelay<T> create() {
return new PublishRelay<T>();
}
/**
* 原子引用訂閱者數組EMPTY
*/
@SuppressWarnings("unchecked")
PublishRelay() {
subscribers = new AtomicReference<PublishDisposable<T>[]>(EMPTY);
}
@Override
protected void subscribeActual(Observer<? super T> t) {
PublishDisposable<T> ps = new PublishDisposable<T>(t, this);
t.onSubscribe(ps);
add(ps);
// if cancellation happened while a successful add, the remove() didn't work
// so we need to do it again
if (ps.isDisposed()) {
remove(ps);
}
}
/**
* 創建一個比原數組大1的數組,複製原數組到新數組,添加訂閱者ps到末尾
*/
void add(PublishDisposable<T> ps) {
for (;;) {
//得到原子引用對象訂閱者數組EMPTY
PublishDisposable<T>[] a = subscribers.get();
int n = a.length;
//創建比EMPTY大1的數組,剛開始EMPTY爲0,大小從1開始,2,3...
@SuppressWarnings("unchecked")
PublishDisposable<T>[] b = new PublishDisposable[n + 1];
//從索引0複製a數組到b數組,放置起始索引0,複製n項
System.arraycopy(a, 0, b, 0, n);
//新添加的訂閱者ps放置在最末尾
b[n] = ps;
if (subscribers.compareAndSet(a, b)) {
return;
}
}
}
/**
*刪除數組中指定訂閱者
*/
@SuppressWarnings("unchecked")
void remove(PublishDisposable<T> ps) {
for (;;) {
PublishDisposable<T>[] a = subscribers.get();
if (a == EMPTY) {
return;
}
int n = a.length;
int j = -1;
//找到待刪除訂閱者索引,賦值給j,退出循環
for (int i = 0; i < n; i++) {
if (a[i] == ps) {
j = i;
break;
}
}
if (j < 0) {
return;
}
PublishDisposable<T>[] b;
if (n == 1) {
b = EMPTY;
} else {
//創建一個大小減1的數組
b = new PublishDisposable[n - 1];
//複製a中前j項到b,要刪除的索引爲j(第j+1個)
System.arraycopy(a, 0, b, 0, j);
//再複製a中j+2開始項之後到b
System.arraycopy(a, j + 1, b, j, n - j - 1);
}
//若原子引用對象和a是同一個對象,用b替換a
if (subscribers.compareAndSet(a, b)) {
return;
}
}
}
@Override
public void accept(T value) {
if (value == null) throw new NullPointerException("value == null");
for (PublishDisposable<T> s : subscribers.get()) {
//發射value給訂閱者
s.onNext(value);
}
}
@Override
public boolean hasObservers() {
return subscribers.get().length != 0;
}
/**
* 封裝訂閱者, 跟蹤其請求並進行取消操作,以便從當前訂閱者數組中刪除自己.
*/
static final class PublishDisposable<T> extends AtomicBoolean implements Disposable {
private static final long serialVersionUID = 3562861878281475070L;
final Observer<? super T> downstream;
final PublishRelay<T> parent;
PublishDisposable(Observer<? super T> actual, PublishRelay<T> parent) {
this.downstream = actual;
this.parent = parent;
}
public void onNext(T t) {
//當前引用對象爲fals,即訂閱狀態,發射這個t
if (!get()) {
downstream.onNext(t);
}
}
@Override
public void dispose() {
//設置引用對象爲true
if (compareAndSet(false, true)) {
parent.remove(this);
}
}
@Override
public boolean isDisposed() {
return get(); //當前引用對象的boolean值
}
}
}
其他兩個大同小異。