1.結構
Rxlifecycle代碼很少,也很好理解,來看核心類。
-
接口ActivityLifecycleProvider
RxFragmentActivity、RxAppCompatActivity、RxFragment等類所有的組件類皆實現這個借口
-
類RxLifecycle
2.詳細分析
以RxAppCompatActivity入手來分析。
-
初始化一個BehaviorSubject,Subject因為它是一個Observer,它可以訂閱一個或多個Observable;又因為它是一個Observable,它可以轉發它收到(Observe)的數據,也可以發射新的數據。Subject的詳細介紹:https://mcxiaoke.gitbooks.io/rxdocs/content/Subject.html
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
-
在activity每個生命的周期Subject發射相對應的事件。
@Override @CallSuper protected void onStart() { super.onStart(); //發送start事件 lifecycleSubject.onNext(ActivityEvent.START); } ....
分析RxLifecycle核心的方法:bindUntilActivityEvent
-
bindUntilActivityEvent也就是調用的bindUntilEvent
private static <T, R> Observable.Transformer<T, T> bindUntilEvent(final Observable<R> lifecycle, //返回 Transformer final R event) { return new Observable.Transformer<T, T>() { @Override public Observable<T> call(Observable<T> source) { return source.takeUntil( lifecycle.takeFirst(new Func1<R, Boolean>() { @Override public Boolean call(R lifecycleEvent) { return lifecycleEvent == event; } }) ); } }; }
這個方法接收兩個參數,lifecycle就是activity里面的BehaviorSubject對象,event就是要我們設置的要在activity哪個生命周期取消訂閱的ActivityEvent對象。
返回參數是Transformer,用來結合compose使用 Transformer相當於一個過濾器,Observable call(Observable source) 接收一個Observable然后經過處理再返回一個Observable
這個方法從里到外一層一層剝開:
lifecycle.takeFirst(new Func1<R, Boolean>() { @Override public Boolean call(R lifecycleEvent) { return lifecycleEvent == event; } })
如果lifecycleEvent == event結果為true,lifecycle既BehaviorSubject對象發射一個數據。
lifecycleEvent是BehaviorSubject發射的數據,既ActivityEvent對象,比如在onStart時候lifecycleSubject.onNext(ActivityEvent.START)發送的ActivityEvent.START。 event是傳遞進來的參數。
接着上看
return source.takeUntil()
lifecycle最核心的就是這個takeUntil。
source就是要調用compose的原始的Observable,就是例子中這個Observable
Observable.interval(1, TimeUnit.SECONDS) .compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE)) ...
來看takeUntil:
Returns an Observable that emits the items emitted by the source Observable until a second Observable emits an item.
如果lifecycle.takeFirst發射了一條數據,takeUntil就回觸發,source Observable就回停止發射數據,執行Unsubscribe,流自動結束。
分析RxLifecycle核心的方法:bindUntilActivityEvent
上代碼
private static <T, R> Observable.Transformer<T, T> bind(Observable<R> lifecycle, final Func1<R, R> correspondingEvents) { ... // Make sure we're truly comparing a single stream to itself final Observable<R> sharedLifecycle = lifecycle.share(); // Keep emitting from source until the corresponding event occurs in the lifecycle return new Observable.Transformer<T, T>() { @Override public Observable<T> call(Observable<T> source) { return source.takeUntil( Observable.combineLatest( sharedLifecycle.take(1).map(correspondingEvents), sharedLifecycle.skip(1), new Func2<R, R, Boolean>() { @Override public Boolean call(R bindUntilEvent, R lifecycleEvent) { return lifecycleEvent == bindUntilEvent; } }) .onErrorReturn(RESUME_FUNCTION) .takeFirst(SHOULD_COMPLETE) ); } }; }
- .share()操作符:
-
來看Observable.combineLatest,這個操作符接收三個參數。
第一個參數:取BehaviorSubject發射的數據中的第一個,然后轉換成對應的生命周期。例如在onStart()中調用了bindToLifecycle,take(1)后的數據是ActivityEvent.START,經過map(),返回ActivityEvent.STOP。
第二個參數:從BehaviorSubject發射的數據中經過.skip(1)操作符,過濾掉第一個數據。例如在onStart()中調用了bindToLifecycle,在后續的生命周期中會收到,ActivityEvent.RESUME、ActivityEvent.PAUSE、ActivityEvent.STOP、ActivityEvent.DESTROY
第三個參數:作用是combineFunction,把前兩個參數最近發射的數據按照規則進行合並。規則是比對兩次事件是否相等,然后合並后數據返回Boolean結果。比如params2發射ActivityEvent.RESUME的時候,和params1發射的ActivityEvent.STOP進行比對,返回false結果;params2發射ActivityEvent.STOP的時候,和params1發射的ActivityEvent.STOP進行比對,返回true結果。
-
onErrorReturn()
private static final Func1<Throwable, Boolean> RESUME_FUNCTION = new Func1<Throwable, Boolean>() { @Override public Boolean call(Throwable throwable) { if (throwable instanceof OutsideLifecycleException) { return true; } Exceptions.propagate(throwable); return false; } };
如果發生錯誤,判斷是否是自定義錯誤類型 OutsideLifecycleException,如果是,則返回true,否則其他錯誤類型返回false。
-
.takeFirst(SHOULD_COMPLETE)
private static final Func1<Boolean, Boolean> SHOULD_COMPLETE = new Func1<Boolean, Boolean>() { @Override public Boolean call(Boolean shouldComplete) { return shouldComplete; } };
返回第一個結果是true的數據。如果combineLatest鏈中返回false,則不發射任何數據。
-
source.takeUntil
如果combineLatest.onErrorReturn.takeFirst鏈返回true,則takeUntil操作符終止訂閱,source Observable就回停止發射數據,執行Unsubscribe,流自動結束。
OVER!