随着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已经很清晰!!