當前版本 2.2.19
RxJava2 (一)訂閱流程源碼閱讀
RxJava2 (二)取消訂閱流程 dispose( ) 源碼閱讀
RxJava2 (三)線程切換源碼閱讀
RxJava2 (四)切換UI主線程源碼閱讀
RxJava2 (五)just操作符源碼閱讀
RxJava2 (六)map操作符源碼閱讀
代碼示例
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("Hello World");
emitter.onComplete();
}
})
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("onSubscribe");
// 取消訂閱後,ObservableEmitter發出的消息,觀察者Observer將不會再收到.
d.dispose();
}
@Override
public void onNext(String s) {
System.out.println("onNext: " + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
梳理對象
Observable
:抽象類,Observable.create(ObservableOnSubscribe<T> source)
最終創建一個ObservableCreate
對象返回.ObservableCreate
:Observable
的子類,實現了subscribeActual()
方法.它內部持有ObservableOnSubscribe
對象引用,ObservableOnSubscribe
:被觀察者發射數據的是在ObservableOnSubscribe.subscribe()
方法中調用CreateEmitter
中的onNext()
,onComplete()
等方法.- 當執行
Observable.subscribe()
最終會調用ObservableCreate.subscribeActual()
,所有的數據發射由這裏開始. CreateEmitter
:它在ObservableCreate.subscribeActual()
執行中被創建,它內部持有Observer引用.- 與取消訂閱流程有關的點是,
CreateEmitter
實現了Disposable接口
綜上:CreateEmitter對象,可以發射數據,可以取消訂閱流程,它向上抽取了兩個接口,一個接口專門封裝了發射數據的方法,一個接口專門處理取消訂閱的方法.
Observer.onSubscribe(Disposable d)
當調用Observable.subscribe()
最終會調用ObservableCreate.subscribeActual()
public final class ObservableCreate<T> extends Observable<T> {
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
// 觀察者在這裏調用了自身的onSubscribe()方法,傳遞過來的是CreateEmitter對象,不過onSubscribe(Disposable d)方法中的參數類型爲Disposable.
observer.onSubscribe(parent);
...
}
}
// Disposable對象就是被當作參數傳遞到onSubscribe()方法中
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
System.out.println("onSubscribe");
// 取消訂閱後,ObservableEmitter發出的消息,觀察者Observer將不會再收到.
d.dispose();
}
@Override
public void onNext(String s) {
System.out.println("onNext: " + s);
}
@Override
public void onError(Throwable e) {
System.out.println("onError");
}
@Override
public void onComplete() {
System.out.println("onComplete");
}
});
d.dispose();
取消訂閱
dispose()
方法的具體實現需要去CreateEmitter
中看
// ObservableCreate.CreateEmitter類
public final class ObservableCreate<T> extends Observable<T> {
static final class CreateEmitter<T> extends AtomicReference<Disposable> implements ObservableEmitter<T>, Disposable {
// 取消訂閱
@Override
public void dispose() {
// 這裏的this就是CreateEmitter對象本身,看下DisposableHelper.dispose()
DisposableHelper.dispose(this);
}
// 判斷是否取消訂閱
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
}
// DisposableHelper類
public enum DisposableHelper implements Disposable {
DISPOSED
;
// field就是剛剛傳遞進來的CreateEmitter對象,CreateEmitter繼承了AtomicReference<Disposable>.
// AtomicReference<Disposable>知識可以看這兩個博客:
// https://www.jianshu.com/p/84c75074fa03
// https://blog.csdn.net/zxc123e/article/details/52057289
public static boolean dispose(AtomicReference<Disposable> field) {
// 獲取AtomicReference<Disposable>對象中的值,不過CreateEmitter對象是直接new出來的,所以其中並沒有值,此時current是爲null.
Disposable current = field.get();
// DISPOSED是一個枚舉
Disposable d = DISPOSED;
if (current != d) {
// 此時current爲null,肯定與d不相等.
// getAndSet(d)意思是將field對象中的舊值設置爲d,並且返回舊值,那麼current肯定還是爲null.
// 執行到這一步,AtomicReference<Disposable>對象中就存在一個枚舉對象了.
current = field.getAndSet(d);
if (current != d) {
if (current != null) {
current.dispose();
}
return true;
}
}
return false;
}
// 判斷傳入的枚舉類是否和當前枚舉類相等.
// 如果相等,代表訂閱已經取消了
// 如果不相等,代表訂閱沒有取消
public static boolean isDisposed(Disposable d) {
return d == DISPOSED;
}
}
emitter.onNext("Hello World")
發射數據,最終會調用到CreateEmitter
中的onNext(T t)
方法,這個過程會判斷訂閱是否取消.下面來看下.
public final class ObservableCreate<T> extends Observable<T> {
static final class CreateEmitter<T> extends AtomicReference<Disposable> implements ObservableEmitter<T>, Disposable {
@Override
public void onNext(T t) {
...
if (!isDisposed()) {
observer.onNext(t);
}
}
// 判斷是否取消訂閱
@Override
public boolean isDisposed() {
// 如果CreateEmitter對象調用了dispose()方法,最終會向CreateEmitter對象中存入一個枚舉對象.
// CreateEmitter.get() 獲取的就是這個枚舉
// 上面有分析過
// 傳入的枚舉對象如果和枚舉類中的枚舉對象地址值相同,代表訂閱已經取消了
// 如果地址值不相同,代表訂閱沒有取消
return DisposableHelper.isDisposed(get());
}
}
}
CompositeDisposable
簡單說下CompositeDisposable
,它可以批量管理RxJava批量取消訂閱操作.
CompositeDisposable mCompositeDisposable = new CompositeDisposable();
// 將所有的disposable對象都由mCompositeDisposable對象保管.
mCompositeDisposable.add(disposable);
下面看下CompositeDisposable
對象的add()
// CompositeDisposable類
public final class CompositeDisposable implements Disposable, DisposableContainer {
volatile boolean disposed; // 這個對象是用來標記當前的CompositeDisposable對象是否已經執行了取消訂閱的操作
@Override
public boolean add(@NonNull Disposable disposable) {
ObjectHelper.requireNonNull(disposable, "disposable is null");
if (!disposed) { // 假如當前CompositeDisposable對象還未執行取消操作
synchronized (this) {
if (!disposed) {// 假如當前CompositeDisposable對象還未執行取消操作
OpenHashSet<Disposable> set = resources; // 創建Set集合
if (set == null) {
set = new OpenHashSet<Disposable>();
resources = set;
}
// 將disposable對象存入集合中
set.add(disposable);
return true;
}
}
}
// 假如當前的CompositeDisposable對象已經執行過了取消訂閱的操作,那麼就對傳入的disposable進行取消操作
disposable.dispose();
return false;
}
// 對CompositeDisposable對象中set集合中的所有disposable進行取消訂閱的操作
@Override
public void dispose() {
if (disposed) {
return;
}
OpenHashSet<Disposable> set;
synchronized (this) {
if (disposed) {
return;
}
disposed = true; // 將標記置爲true,表示CompositeDisposable對象執行過了取消訂閱的操作.
set = resources;
resources = null;
}
dispose(set);
}
void dispose(OpenHashSet<Disposable> set) {
if (set == null) {
return;
}
List<Throwable> errors = null;
Object[] array = set.keys();
for (Object o : array) {
if (o instanceof Disposable) {
try {
// 這裏就是實際執行取消訂閱的地方.
((Disposable) o).dispose();
}...
}
}
...
}
}
CompositeDisposable對象主要用來批量取消訂閱,比如Activity中有多個RxJava訂閱,我想在Activity銷燬的時候統一對這些訂閱進行取消,那麼就可以先將Disposable對象都add到CompositeDisposable對象中,等到Activity執行onDestroy生命週期的時候調用CompositeDisposable對象的dispose(),進行統一取消訂閱操作.