在mvp中使用rxlifecycle避免rxjava的內存泄漏

問題

在使用rxjava的時候,如果不及時解除訂閱,當退出acitivy的時候,異步線程還在執行,對activity還存在引用,此時就會產生內存泄漏。

解決

使用第三方的rxlifecycle能夠很方便的解決這個問題。他可以讓Observable發布的事件和當前的組件綁定,實現生命周期同步。從而實現當前組件生命周期結束時,自動取消對Observable訂閱。
參考blog
廢話說了一大堆,本文主要介紹在mvp中使用rxlifecycle

添加依賴

//處理rxjava內存泄漏
compile 'com.trello.rxlifecycle2:rxlifecycle:2.0.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.0.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.0.1'

建立BaseActivity

將自己的BaseActivity繼承RxAppCompatActivity,或者你自己構建一個RxActivity也可以,看一下RxAppCompatActivity源碼即可。

public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
@Override
@NonNull
@CheckResult
public final Observable<ActivityEvent> lifecycle() {
    return lifecycleSubject.hide();
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
    return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
    return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
@Override
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
@CallSuper
protected void onStart() {
    super.onStart();
    lifecycleSubject.onNext(ActivityEvent.START);
}
@Override
@CallSuper
protected void onResume() {
    super.onResume();
    lifecycleSubject.onNext(ActivityEvent.RESUME);
}
@Override
@CallSuper
protected void onPause() {
    lifecycleSubject.onNext(ActivityEvent.PAUSE);
    super.onPause();
}
@Override
@CallSuper
protected void onStop() {
    lifecycleSubject.onNext(ActivityEvent.STOP);
    super.onStop();
}
@Override
@CallSuper
protected void onDestroy() {
    lifecycleSubject.onNext(ActivityEvent.DESTROY);
    super.onDestroy();
}}

接口

interface Iview{
    LifecycleTransformer bindLifecycle();
}

Activity中實現Iview接口的bindLifecycle()方法

@Override
public LifecycleTransformer bindLifecycle() {
    //RxAppCompatActivity中的方法bindToLifecycle()
    LifecycleTransformer objectLifecycleTransformer = bindToLifecycle();
    return objectLifecycleTransformer;
}

presenter中使用

關鍵代碼.compose(iview.bindLifecycle())
用的mvp模式,網絡請求用的rxjava加retrofite。mvp和網絡框架這里就不介紹了,網上有很多。
其中iview是activity傳過來的接口,這里或者是activity的弱引用對象等等,反正就是用來調用activity中的方法,聯系activity與presenter的。換成你自己的就行了。
參考blog

RxRetrofitFactory.create(MyService.class).getRecords("自己網絡請求的參數")
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .compose(iview.bindLifecycle())
            .subscribe(new Observer<Message<List<ResultBean>>>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.e("onSubscribe","onSubscribe--------------------------------------");
                    //d.dispose();//解除訂閱(在這里解除訂閱,后面的都不會執行了)
                }
                @Override
                public void onNext(Message<List<ResultBean>> records) {
                    Log.e("onNext","onNext--------------------------------------");
                    List<ResultBean> recordList=records.Result;
                    iview.addRecordToList(recordList);
                }
                @Override
                public void onError(Throwable e) {
                    Log.e("onError","onError--------------------------------------");
                    iview.showLoading(false);
                }
                @Override
                public void onComplete() {
                    Log.e("onComplete","onComplete,--------------------------------------");
                    iview.showLoading(false);
                }
            });

`

后記

默認bindToLifecycle會在onPause方法執行前解除綁定,這樣,在我們請求還未得到結果時,我們進入下一個頁面,這個請求就會中斷。為了避免這種情況,請使用compose(this.<Integer>bindUntilEvent(ActivityEvent.DESTROY))

Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            SystemClock.sleep(10000);
            emitter.onNext(1);
        }
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .compose(this.<Integer>bindUntilEvent(ActivityEvent.DESTROY))
//                .compose(this.<Integer>bindToLifecycle())
            .subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(Disposable d) {
                    AppUtils.log("rxlife","--------onSubscribe");
                }
                @Override
                public void onNext(Integer integer) {
                    AppUtils.log("rxlife","--------onNext");
                }
                @Override
                public void onError(Throwable e) {
                    AppUtils.log("rxlife","--------onError");
                }
                @Override
                public void onComplete() {
                    AppUtils.log("rxlife","--------onComplete");
                }
            });

使用compose(this.<Integer>bindUntilEvent(ActivityEvent.DESTROY))的結果
qian.png

使用.compose(this.<Integer>bindToLifecycle())的結果
前.png

上面兩個方法根據自己需要,用一個就可以了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容