RxLifecycle详细解析
一、介紹
RxLifecycle目的:解決RxJava使用中的內(nèi)存泄漏問題。
例如,當(dāng)使用RxJava訂閱并執(zhí)行耗時(shí)任務(wù)后,當(dāng)Activity被finish時(shí),如果耗時(shí)任務(wù)還未完成,沒有及時(shí)取消訂閱,就會(huì)導(dǎo)致Activity無(wú)法被回收,從而引發(fā)內(nèi)存泄漏。
為了解決這個(gè)問題,就產(chǎn)生了RxLifecycle,讓RxJava變得有生命周期感知,使得其能及時(shí)取消訂閱,避免出現(xiàn)內(nèi)存泄漏問題。
二、使用
首先來(lái)介紹下RxLifecycle的使用。
1.添加依賴
implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1' 復(fù)制代碼2.繼承容器類
Activity/Fragment需要繼承RxAppCompatActivity/RxFragment,主要支持如下幾種容器類:
只需要在項(xiàng)目中針對(duì)base類的容器中繼承實(shí)現(xiàn)對(duì)應(yīng)的Rx類即可,這一步主要是對(duì)生命周期的回調(diào)事件進(jìn)行監(jiān)聽。3.綁定容器生命周期
以Activity為例,主要有如下兩種方法:
bindUntilEvent(@NonNull ActivityEvent event) 復(fù)制代碼bindToLifecycle() 復(fù)制代碼針對(duì)Fragment也有同樣的兩種方法,只是方法名會(huì)有所不同。
下面詳細(xì)介紹這兩種方法的區(qū)別:
bindUntilEvent
該方法指定在哪個(gè)生命周期方法調(diào)用時(shí)取消訂閱。
其中ActivityEvent是一個(gè)枚舉類,對(duì)應(yīng)于Activity的生命周期。
public enum ActivityEvent {CREATE,START,RESUME,PAUSE,STOP,DESTROY} 復(fù)制代碼具體使用示例:
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)Observable.interval(1, TimeUnit.SECONDS).doOnDispose {Log.i(TAG, "Unsubscribing subscription from onDestory()")}.compose(bindUntilEvent(ActivityEvent.DESTROY)).subscribe {Log.i(TAG, "Started in onCreate(), running until in onDestroy(): $it")}} 復(fù)制代碼指定在生命周期onDestory()時(shí),取消訂閱。
bindToLifecycle
在某個(gè)生命周期進(jìn)行綁定,在對(duì)應(yīng)的生命周期進(jìn)行訂閱解除。
具體使用示例:
override fun onResume() {super.onResume()Observable.interval(1, TimeUnit.SECONDS).doOnDispose {Log.i(TAG, "Unsubscribing subscription from onPause()")}.compose(bindToLifecycle()).subscribe {Log.i(TAG, "Started in onResume(), running until in onPause(): $it")}} 復(fù)制代碼在onResume()進(jìn)行綁定訂閱,則在onPause()進(jìn)行解除訂閱,生命周期是兩兩對(duì)應(yīng)的。
三、原理解析
1.compose
首先來(lái)了解一下compose操作符。
compose(bindToLifecycle()) compose(bindUntilEvent(ActivityEvent.DESTROY)) 復(fù)制代碼如上所示,兩種綁定生命周期的方式,都是通過compose操作符進(jìn)行實(shí)現(xiàn)的。
compose一般情況下可以配合Transformer使用,以實(shí)現(xiàn)將一種類型的Observable轉(zhuǎn)換成另一種類型的Observable,保證調(diào)用的鏈?zhǔn)浇Y(jié)構(gòu)。
那么接下來(lái)看該操作符在RxLifecycle中的應(yīng)用,從bindToLifecycle和bindUntilEvent入手。
2.BehaviorSubject
public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();@Override@NonNull@CheckResultpublic final Observable<ActivityEvent> lifecycle() {return lifecycleSubject.hide();}@Override@NonNull@CheckResultpublic final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {return RxLifecycle.bindUntilEvent(lifecycleSubject, event);}@Override@NonNull@CheckResultpublic final <T> LifecycleTransformer<T> bindToLifecycle() {return RxLifecycleAndroid.bindActivity(lifecycleSubject);}@Override@CallSuperprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);lifecycleSubject.onNext(ActivityEvent.CREATE);}@Override@CallSuperprotected void onStart() {super.onStart();lifecycleSubject.onNext(ActivityEvent.START);}@Override@CallSuperprotected void onResume() {super.onResume();lifecycleSubject.onNext(ActivityEvent.RESUME);}@Override@CallSuperprotected void onPause() {lifecycleSubject.onNext(ActivityEvent.PAUSE);super.onPause();}@Override@CallSuperprotected void onStop() {lifecycleSubject.onNext(ActivityEvent.STOP);super.onStop();}@Override@CallSuperprotected void onDestroy() {lifecycleSubject.onNext(ActivityEvent.DESTROY);super.onDestroy();} } 復(fù)制代碼RxAppCompatActivity中有一個(gè)關(guān)鍵對(duì)象BehaviorSubject
BehaviorSubject會(huì)發(fā)送離訂閱最近的上一個(gè)值,沒有上一個(gè)值的時(shí)候會(huì)發(fā)送默認(rèn)值。如下圖:
所以lifecycleSubject會(huì)根據(jù)綁定訂閱的時(shí)期,不斷發(fā)送接下來(lái)的生命周期事件ActivityEvent。
3.LifecycleTransformer
接下來(lái)繼續(xù)看源碼,bindToLifecycle和bindUntilEvent都返回了一個(gè)LifecycleTransformer對(duì)象,那么LifecycleTransformer到底有什么用?
@ParametersAreNonnullByDefault public final class LifecycleTransformer<T> implements ObservableTransformer<T, T>,FlowableTransformer<T, T>,SingleTransformer<T, T>,MaybeTransformer<T, T>,CompletableTransformer {final Observable<?> observable;LifecycleTransformer(Observable<?> observable) {checkNotNull(observable, "observable == null");this.observable = observable;}@Overridepublic ObservableSource<T> apply(Observable<T> upstream) {return upstream.takeUntil(observable);}@Overridepublic Publisher<T> apply(Flowable<T> upstream) {return upstream.takeUntil(observable.toFlowable(BackpressureStrategy.LATEST));}@Overridepublic SingleSource<T> apply(Single<T> upstream) {return upstream.takeUntil(observable.firstOrError());}@Overridepublic MaybeSource<T> apply(Maybe<T> upstream) {return upstream.takeUntil(observable.firstElement());}@Overridepublic CompletableSource apply(Completable upstream) {return Completable.ambArray(upstream, observable.flatMapCompletable(Functions.CANCEL_COMPLETABLE));}@Overridepublic boolean equals(Object o) {if (this == o) { return true; }if (o == null || getClass() != o.getClass()) { return false; }LifecycleTransformer<?> that = (LifecycleTransformer<?>) o;return observable.equals(that.observable);}@Overridepublic int hashCode() {return observable.hashCode();}@Overridepublic String toString() {return "LifecycleTransformer{" +"observable=" + observable +'}';} } 復(fù)制代碼LifecycleTransformer實(shí)現(xiàn)了各種Transformer接口,能夠?qū)⒁粋€(gè) Observable/Flowable/Single/Completable/Maybe 對(duì)象轉(zhuǎn)換成另一個(gè) Observable/Flowable/Single/Completable/Maybe對(duì)象。正好配合上文的compose操作符,使用在鏈?zhǔn)秸{(diào)用中。
4.takeUntil
接下來(lái)到了關(guān)鍵了,LifecycleTransformer到底把原來(lái)的Observable對(duì)象轉(zhuǎn)換成了什么樣子?
這就需要了解takeUntil操作符了!
當(dāng)?shù)诙€(gè)Observable發(fā)射了一項(xiàng)數(shù)據(jù)或者終止時(shí),丟棄原Observable發(fā)射的任何數(shù)據(jù)。所謂的第二個(gè)Observable,即傳入takeUntil中的Observable對(duì)象。理解了該操作符的作用,那么你可能就明白了,RxLifecycle就是通過監(jiān)聽第二個(gè)Observable發(fā)射的數(shù)據(jù),來(lái)解除訂閱。
那么這第二個(gè)Observable是誰(shuí)?
不就是在創(chuàng)建LifecycleTransformer的時(shí)候傳入構(gòu)造函數(shù)中的嘛,那就來(lái)尋找一下什么時(shí)候創(chuàng)建的該對(duì)象即可。
從頭開始捋一捋:
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {return RxLifecycle.bindUntilEvent(lifecycleSubject, event);} 復(fù)制代碼該方法返回了LifecycleTransformer對(duì)象,繼續(xù)向下追溯。
public static <T, R> LifecycleTransformer<T> bindUntilEvent(@Nonnull final Observable<R> lifecycle,@Nonnull final R event) {checkNotNull(lifecycle, "lifecycle == null");checkNotNull(event, "event == null");return bind(takeUntilEvent(lifecycle, event)); }private static <R> Observable<R> takeUntilEvent(final Observable<R> lifecycle, final R event) {return lifecycle.filter(new Predicate<R>() {@Overridepublic boolean test(R lifecycleEvent) throws Exception {return lifecycleEvent.equals(event);}}); } 復(fù)制代碼繼續(xù)追蹤,馬上接近真相。
public static <T, R> LifecycleTransformer<T> bind(@Nonnull final Observable<R> lifecycle) {return new LifecycleTransformer<>(lifecycle); } 復(fù)制代碼在該方法中創(chuàng)建了該對(duì)象,并傳入了一個(gè)Observable對(duì)象,通過上面方法即可知道該對(duì)象就是BehaviorSubject對(duì)象。
那么該對(duì)象在什么時(shí)候發(fā)送第一次數(shù)據(jù)呢?
這就要看上面的takeUntilEvent方法了。
關(guān)鍵在這一句lifecycleEvent.equals(event),只有當(dāng)BehaviorSubject發(fā)送的ActivityEvent的值等于解除綁定的生命周期時(shí),才會(huì)發(fā)送第一次數(shù)據(jù)。那么當(dāng)發(fā)送第一次數(shù)據(jù)時(shí),根據(jù)上面的分析就會(huì)解除訂閱的綁定。
那么針對(duì)bindToLifecycle方法,是進(jìn)行怎樣的操作,使得在對(duì)應(yīng)的生命周期進(jìn)行解除訂閱呢?
還是繼續(xù)看源碼。
public final <T> LifecycleTransformer<T> bindToLifecycle() {return RxLifecycleAndroid.bindActivity(lifecycleSubject);} 復(fù)制代碼public static <T> LifecycleTransformer<T> bindActivity(@NonNull final Observable<ActivityEvent> lifecycle) {return bind(lifecycle, ACTIVITY_LIFECYCLE); } 復(fù)制代碼其中ACTIVITY_LIFECYCLE為:
private static final Function<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =new Function<ActivityEvent, ActivityEvent>() {@Overridepublic ActivityEvent apply(ActivityEvent lastEvent) throws Exception {switch (lastEvent) {case CREATE:return ActivityEvent.DESTROY;case START:return ActivityEvent.STOP;case RESUME:return ActivityEvent.PAUSE;case PAUSE:return ActivityEvent.STOP;case STOP:return ActivityEvent.DESTROY;case DESTROY:throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it.");default:throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");}}}; 復(fù)制代碼該函數(shù)的功能是會(huì)根據(jù)傳入的生命周期事件,返回對(duì)應(yīng)的生命周期,如CREATE→DESTROY。看來(lái)通過該函數(shù)就可以實(shí)現(xiàn)在對(duì)應(yīng)生命周期解綁了。
不過還需要一系列操作符的協(xié)助,繼續(xù)看源碼。
public static <T, R> LifecycleTransformer<T> bind(@Nonnull Observable<R> lifecycle,@Nonnull final Function<R, R> correspondingEvents) {checkNotNull(lifecycle, "lifecycle == null");checkNotNull(correspondingEvents, "correspondingEvents == null");return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));}private static <R> Observable<Boolean> takeUntilCorrespondingEvent(final Observable<R> lifecycle,final Function<R, R> correspondingEvents) {return Observable.combineLatest(lifecycle.take(1).map(correspondingEvents),lifecycle.skip(1),new BiFunction<R, R, Boolean>() {@Overridepublic Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {return lifecycleEvent.equals(bindUntilEvent);}}).onErrorReturn(Functions.RESUME_FUNCTION).filter(Functions.SHOULD_COMPLETE);} 復(fù)制代碼詳細(xì)看一下takeUntilCorrespondingEvent方法。
5.take
首先看一下take操作符,很簡(jiǎn)單。
take(int)用一個(gè)整數(shù)n作為一個(gè)參數(shù),只發(fā)射前面的n項(xiàng),如下圖:
那么對(duì)應(yīng)lifecycle.take(1).map(correspondingEvents),即獲取發(fā)送的第一個(gè)生命周期事件,再通過上面對(duì)應(yīng)的函數(shù),轉(zhuǎn)換為響應(yīng)的生命周期。如果在onCreate中進(jìn)行綁定,那么第一個(gè)發(fā)送的就是CREATE,返回的就是對(duì)應(yīng)的DESTORY。
6.skip
skip(int)忽略O(shè)bservable發(fā)射的前n項(xiàng)數(shù)據(jù)
lifecycle.skip(1),如果在onCreate中進(jìn)行綁定,那么剩余的就是START,RESUME,PAUSE,STOP,DESTROY
7. combineLatest
最后還需要一個(gè)關(guān)鍵的操作符combineLatest,來(lái)完成對(duì)應(yīng)生命周期的解除訂閱。
combineLatest操作符可以將2~9個(gè)Observable發(fā)射的數(shù)據(jù)組裝起來(lái)然后再發(fā)射出來(lái)。不過還有兩個(gè)前提:
- 所有的Observable都發(fā)射過數(shù)據(jù)。
- 滿足上面條件的時(shí)候任何一個(gè)Observable發(fā)射一個(gè)數(shù)據(jù),就將所有Observable最新發(fā)射的數(shù)據(jù)按照提供的函數(shù)組裝起來(lái)發(fā)射出去。
具體示例,如下圖所示:
按照第三個(gè)參數(shù)的函數(shù),將lifecycle.take(1).map(correspondingEvents)和lifecycle.skip(1),進(jìn)行combine
new BiFunction<R, R, Boolean>() {@Overridepublic Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {return lifecycleEvent.equals(bindUntilEvent);}} 復(fù)制代碼那么結(jié)果是
false,false,false,false,true 復(fù)制代碼之后的onErrorReturn和filter是對(duì)異常的處理和判斷是否應(yīng)該結(jié)束訂閱:
//異常處理 static final Function<Throwable, Boolean> RESUME_FUNCTION = new Function<Throwable, Boolean>() {@Overridepublic Boolean apply(Throwable throwable) throws Exception {if (throwable instanceof OutsideLifecycleException) {return true;}//noinspection ThrowableResultOfMethodCallIgnoredExceptions.propagate(throwable);return false;}};//是否應(yīng)該取消訂閱,依賴于上游的booleanstatic final Predicate<Boolean> SHOULD_COMPLETE = new Predicate<Boolean>() {@Overridepublic boolean test(Boolean shouldComplete) throws Exception {return shouldComplete;}}; 復(fù)制代碼所以,按照上面的例子,如果在onCreate()方法中進(jìn)行綁定,那么在onDestory()方法中就會(huì)對(duì)應(yīng)的解除訂閱。
四、總結(jié)
通過上面的分析,可以了解RxLifecycle的使用以及原理。
學(xué)習(xí)RxLifecycle的過程中,更加體會(huì)到了對(duì)于觀察者模式的使用,以及RxJava操作符的強(qiáng)大,各種操作符幫我們實(shí)現(xiàn)一些列的轉(zhuǎn)換。
總結(jié)
以上是生活随笔為你收集整理的RxLifecycle详细解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛谷P2863 [USACO06JAN]
- 下一篇: DOM 操作