日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RxLifecycle详细解析

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RxLifecycle详细解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、介紹

RxLifecycle目的:解決RxJava使用中的內存泄漏問題。

例如,當使用RxJava訂閱并執行耗時任務后,當Activity被finish時,如果耗時任務還未完成,沒有及時取消訂閱,就會導致Activity無法被回收,從而引發內存泄漏。

為了解決這個問題,就產生了RxLifecycle,讓RxJava變得有生命周期感知,使得其能及時取消訂閱,避免出現內存泄漏問題。

二、使用

首先來介紹下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' 復制代碼

2.繼承容器類

Activity/Fragment需要繼承RxAppCompatActivity/RxFragment,主要支持如下幾種容器類:

只需要在項目中針對base類的容器中繼承實現對應的Rx類即可,這一步主要是對生命周期的回調事件進行監聽。

3.綁定容器生命周期

以Activity為例,主要有如下兩種方法:

bindUntilEvent(@NonNull ActivityEvent event) 復制代碼bindToLifecycle() 復制代碼

針對Fragment也有同樣的兩種方法,只是方法名會有所不同。

下面詳細介紹這兩種方法的區別:

bindUntilEvent

該方法指定在哪個生命周期方法調用時取消訂閱。

其中ActivityEvent是一個枚舉類,對應于Activity的生命周期。

public enum ActivityEvent {CREATE,START,RESUME,PAUSE,STOP,DESTROY} 復制代碼

具體使用示例:

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")}} 復制代碼

指定在生命周期onDestory()時,取消訂閱。

bindToLifecycle

在某個生命周期進行綁定,在對應的生命周期進行訂閱解除。

具體使用示例:

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")}} 復制代碼

在onResume()進行綁定訂閱,則在onPause()進行解除訂閱,生命周期是兩兩對應的。

三、原理解析

1.compose

首先來了解一下compose操作符。

compose(bindToLifecycle()) compose(bindUntilEvent(ActivityEvent.DESTROY)) 復制代碼

如上所示,兩種綁定生命周期的方式,都是通過compose操作符進行實現的。

compose一般情況下可以配合Transformer使用,以實現將一種類型的Observable轉換成另一種類型的Observable,保證調用的鏈式結構。

那么接下來看該操作符在RxLifecycle中的應用,從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();} } 復制代碼

RxAppCompatActivity中有一個關鍵對象BehaviorSubject

BehaviorSubject會發送離訂閱最近的上一個值,沒有上一個值的時候會發送默認值。如下圖:

所以lifecycleSubject會根據綁定訂閱的時期,不斷發送接下來的生命周期事件ActivityEvent。

3.LifecycleTransformer

接下來繼續看源碼,bindToLifecycle和bindUntilEvent都返回了一個LifecycleTransformer對象,那么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 +'}';} } 復制代碼

LifecycleTransformer實現了各種Transformer接口,能夠將一個 Observable/Flowable/Single/Completable/Maybe 對象轉換成另一個 Observable/Flowable/Single/Completable/Maybe對象。正好配合上文的compose操作符,使用在鏈式調用中。

4.takeUntil

接下來到了關鍵了,LifecycleTransformer到底把原來的Observable對象轉換成了什么樣子?

這就需要了解takeUntil操作符了!

當第二個Observable發射了一項數據或者終止時,丟棄原Observable發射的任何數據。所謂的第二個Observable,即傳入takeUntil中的Observable對象。

理解了該操作符的作用,那么你可能就明白了,RxLifecycle就是通過監聽第二個Observable發射的數據,來解除訂閱。

那么這第二個Observable是誰?

不就是在創建LifecycleTransformer的時候傳入構造函數中的嘛,那就來尋找一下什么時候創建的該對象即可。

從頭開始捋一捋:

public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {return RxLifecycle.bindUntilEvent(lifecycleSubject, event);} 復制代碼

該方法返回了LifecycleTransformer對象,繼續向下追溯。

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);}}); } 復制代碼

繼續追蹤,馬上接近真相。

public static <T, R> LifecycleTransformer<T> bind(@Nonnull final Observable<R> lifecycle) {return new LifecycleTransformer<>(lifecycle); } 復制代碼

在該方法中創建了該對象,并傳入了一個Observable對象,通過上面方法即可知道該對象就是BehaviorSubject對象。

那么該對象在什么時候發送第一次數據呢?

這就要看上面的takeUntilEvent方法了。

關鍵在這一句lifecycleEvent.equals(event),只有當BehaviorSubject發送的ActivityEvent的值等于解除綁定的生命周期時,才會發送第一次數據。那么當發送第一次數據時,根據上面的分析就會解除訂閱的綁定。

那么針對bindToLifecycle方法,是進行怎樣的操作,使得在對應的生命周期進行解除訂閱呢?

還是繼續看源碼。

public final <T> LifecycleTransformer<T> bindToLifecycle() {return RxLifecycleAndroid.bindActivity(lifecycleSubject);} 復制代碼public static <T> LifecycleTransformer<T> bindActivity(@NonNull final Observable<ActivityEvent> lifecycle) {return bind(lifecycle, ACTIVITY_LIFECYCLE); } 復制代碼

其中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");}}}; 復制代碼

該函數的功能是會根據傳入的生命周期事件,返回對應的生命周期,如CREATE→DESTROY??磥硗ㄟ^該函數就可以實現在對應生命周期解綁了。

不過還需要一系列操作符的協助,繼續看源碼。

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);} 復制代碼

詳細看一下takeUntilCorrespondingEvent方法。

5.take

首先看一下take操作符,很簡單。

take(int)用一個整數n作為一個參數,只發射前面的n項,如下圖:

那么對應lifecycle.take(1).map(correspondingEvents),即獲取發送的第一個生命周期事件,再通過上面對應的函數,轉換為響應的生命周期。如果在onCreate中進行綁定,那么第一個發送的就是CREATE,返回的就是對應的DESTORY。

6.skip

skip(int)忽略Observable發射的前n項數據

lifecycle.skip(1),如果在onCreate中進行綁定,那么剩余的就是START,RESUME,PAUSE,STOP,DESTROY

7. combineLatest

最后還需要一個關鍵的操作符combineLatest,來完成對應生命周期的解除訂閱。

combineLatest操作符可以將2~9個Observable發射的數據組裝起來然后再發射出來。不過還有兩個前提:

  • 所有的Observable都發射過數據。
  • 滿足上面條件的時候任何一個Observable發射一個數據,就將所有Observable最新發射的數據按照提供的函數組裝起來發射出去。

具體示例,如下圖所示:

按照第三個參數的函數,將lifecycle.take(1).map(correspondingEvents)和lifecycle.skip(1),進行combine

new BiFunction<R, R, Boolean>() {@Overridepublic Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {return lifecycleEvent.equals(bindUntilEvent);}} 復制代碼

那么結果是

false,false,false,false,true 復制代碼

之后的onErrorReturn和filter是對異常的處理和判斷是否應該結束訂閱:

//異常處理 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;}};//是否應該取消訂閱,依賴于上游的booleanstatic final Predicate<Boolean> SHOULD_COMPLETE = new Predicate<Boolean>() {@Overridepublic boolean test(Boolean shouldComplete) throws Exception {return shouldComplete;}}; 復制代碼

所以,按照上面的例子,如果在onCreate()方法中進行綁定,那么在onDestory()方法中就會對應的解除訂閱。

四、總結

通過上面的分析,可以了解RxLifecycle的使用以及原理。

學習RxLifecycle的過程中,更加體會到了對于觀察者模式的使用,以及RxJava操作符的強大,各種操作符幫我們實現一些列的轉換。

總結

以上是生活随笔為你收集整理的RxLifecycle详细解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。