Rxjava的泄露解決方案——rxlifecycle的使用和原理分析

    最近在公司沒有開發任務,就完整過了一下ReactiveX的rxjava,在考慮使用場景時,就考慮到異步操作可能會造成泄露問題,所以網上搜索就發現relifecycle這個輔助庫。下面就記錄一下它的使用和實現原理

需要在build.gradle中配置:

implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.0'
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.0'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.0'

基礎使用:

public class MainActivity extends RxAppCompatActivity {

    String TAG = "tag";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("text");
            }
        }).subscribeOn(Schedulers.io()).compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE)).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, "onNext: " + s);
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onComplete() {

            }
        });
    }
}

在rxjava的基礎上只要修改兩處即可能實現接入:

1、對應繼承的Activity、Fragment更換爲繼承RxActivity和RxFragment,在輔助庫還適配其他類型。

2、綁定對應的生命週期監聽

relifecycler有兩種綁定監聽的形式:

public interface LifecycleProvider<E> {
    /**
     * 返回一系列生命週期事件
     */
    @Nonnull
    @CheckReturnValue
    Observable<E> lifecycle();

    /**
     * 1、當發生某個特定事件時斷開監聽,由我們自己指定
     *
     * @param 枚舉類ActivityEvent
     * @reture 一個可重複使用的LifecycleTransformer
     */
    @Nonnull
    @CheckReturnValue
    <T> LifecycleTransformer<T> bindUntilEvent(@Nonnull E event);

    /**
     * 2、綁定源,直到發生下一個合理事件,自動指定
     * @return 一個可重複使用的LifecycleTransformer
     */
    @Nonnull
    @CheckReturnValue
    <T> LifecycleTransformer<T> bindToLifecycle();
}

第二種自動指定規則的代碼塊如下:

private static final Function<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =
        new Function<ActivityEvent, ActivityEvent>() {
            @Override
            public ActivityEvent apply(ActivityEvent lastEvent) throws Exception {
                switch (lastEvent) {
                    case CREATE: // 在onCreate方法中,和下一個方法出現之前的註冊監聽
                        return ActivityEvent.DESTROY;
                    case START: // 在onStart方法中,和下一個方法出現之前的註冊監聽
                        return ActivityEvent.STOP;
                    case RESUME: // 在onResume方法中,和下一個方法出現之前的註冊監聽
                        return ActivityEvent.PAUSE;
                    case PAUSE: // 在onPause方法中,和下一個方法出現之前的註冊監聽
                        return ActivityEvent.STOP;
                    case STOP:  // 在onStop方法中,和下一個方法出現之前的註冊監聽
                        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");
                }
            }
        };

rxlofecycler的使用挺簡單的,其實原理也是十分簡單,其實這是利用Rxjava的takeUntil關鍵字

takeUtil關鍵字作用:TakeUntil訂閱並開始鏡像源Observable。 它還監視您提供的第二個Observable。 如果第二個Observable發出一個項目或發送終止通知,則TakeUntil返回的Observable將停止鏡像源Observable並終止。這第二個Observable就是維護在RxActivity中。

我寫了一個例子,模擬了bindUntilEvent的功能實現

// 第二個Observable(即RxActivityz中維護的Observable)
final BehaviorSubject<String> behaviorSubject = BehaviorSubject.create();
    behaviorSubject.filter(new Predicate<String>() {
        @Override
        public boolean test(String s) throws Exception {
            return "end".equals(s);
        }
    }).subscribe(new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(String s) {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    });
    // 第一個Observable(即我們自己的Observable)
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            while (true) {
                emitter.onNext("aa");
            }
        }
    }).subscribeOn(Schedulers.io()).compose(new ObservableTransformer<String, String>() {
        @Override
        public ObservableSource<String> apply(Observable<String> upstream) {
            return upstream.takeUntil(behaviorSubject);
        }
    }).subscribe(new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.d(TAG, "onSubscribe: ");
        }

        @Override
        public void onNext(String s) {
            Log.d(TAG, "onNext: " + s);
        }

        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
        }
	
        @Override
        public void onComplete() {

        }
    });
       
    // 一秒鐘後第二個Observable發出特定事件(“end”),第一個Observable中止取消監聽
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            behaviorSubject.onNext("end");
        }
    }, 1000);
}

rxlifecycler的源碼挺少,也挺容易看的,可以通過上面這個例子對照源碼進行分析就可以很容易明白rxlifecycler的實現,不過最好不要在BaseActivity中直接繼承RxActivity,這樣不管在使不使用Rxjava的情況,每個Activity都會有一個Observable的存在,這點需要斟酌一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章