隨着RxJava及RxAndroid的逐漸推廣,使用者越來越多,但是有一個問題,RxJava的使用不當極有可能會導致內存泄漏
目前網上對RxJava的內存泄漏有幾種方案:
1、RxLifecycle
2、AutoDispose
3、自己封裝,手動爲RxJava的每一次訂閱進行控制,在指定的時機進行取消訂閱
個人對RxLifecycle使用比較多,簡單直接,並且能夠在Activity/Fragment容器的指定生命週期取消訂閱
此處不對AutoDispose作分析,原理大致相同
1、依賴並使用RxLifecycle
- 1、首先在build.gradle文件中添加依賴
compile 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
- 2、配置Activity/Fragment容器
Activity/Fragment需繼承其中的RxActivity/RxFragment
代碼如下:
public abstract class BaseActivity extends RxActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(initActivityLayoutID());
initUI();
test();
}
/**
* 初始化Activity的佈局ID
*/
protected abstract int initActivityLayoutID();
/**
* 初始化UI
*/
protected abstract void initUI();
@Override
public LifecycleProvider getLifecycleProvider() {
return this;
}
private void test(){
// 當執行onDestory()時, 自動解除訂閱
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose(new Action() {
@Override
public void run() throws Exception {
Log.i(TAG, "Unsubscribing subscription from onCreate()");
}
})
.compose(getLifecycleProvider())
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long num) throws Exception {
Log.i(TAG, "Started in onCreate(), running until onDestory(): " + num);
}
});
}
}
只需要三步:依賴、繼承、compose操作符,即可完成在容器的指定生命週期內,RxJava的自動取消訂閱。
2、分析原理(以RxActivity爲例)
2.1、RxActivity
public abstract class RxActivity extends Activity 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);
}
//實際上返回了一個LifecycleTransformer
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
//Activity不同的生命週期,BehaviorSubject對象會發射對應的ActivityEvent
@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();
}
}
關於RxJava 中Subject裏的BehaviorSubject原理,這個BehaviorSubject會在不同的生命週期發射不同的ActivityEvent,比如在onCreate()生命週期發射ActivityEvent.CREATE,在onStop()發射ActivityEvent.STOP
2.2、LifecycleTransformer
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;
}
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
//當observable爲true是終止
return upstream.takeUntil(observable);
}
3、回過頭看bindToLifecycle,本質上RxActivity 中的BehaviorSubject成員變量(它本身就是一個Observable)!
public abstract class RxActivity extends Activity implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
@Override
@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
return RxLifecycleAndroid.bindActivity(lifecycleSubject);
}
3.1、RxLifecycleAndroid
public class RxLifecycleAndroid {
***省略代碼
@NonNull
@CheckResult
public static <T> LifecycleTransformer<T> bindActivity(@NonNull final Observable<ActivityEvent> lifecycle) {
return bind(lifecycle, ACTIVITY_LIFECYCLE);
}
***省略代碼
// Figures out which corresponding next lifecycle event in which to unsubscribe, for Activities
private static final Function<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =
new Function<ActivityEvent, ActivityEvent>() {
@Override
public 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");
}
}
};
}
***省略代碼
}
3.2、RxLifecycle
public class RxLifecycle {
***省略代碼
@Nonnull
@CheckReturnValue
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>() {
@Override
public Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(bindUntilEvent);
}
})
.onErrorReturn(Functions.RESUME_FUNCTION)
.filter(Functions.SHOULD_COMPLETE);
}
}
最終發現是調用combineLatest方法,逐步分析一下
1、lifecycle.take(1)指的是最近發射的事件,比如說我們在onCreate()中執行了bindToLifecycle,那麼lifecycle.take(1)指的就是ActivityEvent.CREATE,經過map(correspondingEvents),這個map中傳的函數就是 RxLifecycleAndroid中的ACTIVITY_LIFECYCLE。
也就是說,lifecycle.take(1).map(correspondingEvents)實際上是返回了 CREATE 對應的事件 DESTROY ,它意味着本次訂閱將在Activity的onDestory進行取消
2、lifecycle.skip(1)就簡單了,除去第一個保留剩下的,以ActivityEvent.Create爲例,這裏就剩下:
ActivityEvent.START
ActivityEvent.RESUME
ActivityEvent.PAUSE
ActivityEvent.STOP
ActivityEvent.DESTROY
3、第三個參數 意味着,lifecycle.take(1).map(correspondingEvents)的序列和 lifecycle.skip(1)進行combine,形成一個新的序列:
false,false,fasle,false,true
即是說,當Activity走到onStart生命週期時,爲false,這次訂閱不會取消,直到onDestroy,爲true,訂閱取消
4、而後的onErrorReturn和filter是對異常的處理和判斷是否應該結束訂閱:
//異常處理
static final Function<Throwable, Boolean> RESUME_FUNCTION = new Function<Throwable, Boolean>() {
@Override
public Boolean apply(Throwable throwable) throws Exception {
if (throwable instanceof OutsideLifecycleException) {
return true;
}
Exceptions.propagate(throwable);
return false;
}
};
//是否應該取消訂閱,可以看到,這依賴於上游的boolean
static final Predicate<Boolean> SHOULD_COMPLETE = new Predicate<Boolean>() {
@Override
public boolean test(Boolean shouldComplete) throws Exception {
return shouldComplete;
}
};
至此對RxLifecycle已經很清晰!!