前言:
项目中用到了RxJava在异步线程中执行好事任务,然后在主线中处理结果。这也是RxJava最常用的场景。代码如下,如果直接这样使用可能会造成内存泄漏的,任务要执行5秒,Activity可能都finish了,任务还没执行完。
java
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
//模拟耗时任务
Thread.sleep(1000 * 5);
emitter.onNext("hello world");
}
}).subscribeOn(Schedulers.io())//线程池执行耗时任务
.observeOn(AndroidSchedulers.mainThread())//主线程处理结果
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
//结果回调
Log.i("tag", "accept " + s);
}
});
RxJava为什么会内存泄漏。
因为匿名内部类会持有外部类的引用。如果在是 Activity 中使用,则 Activity 则会Consumer的匿名内部类持有,而 Comsumer 的匿名实例则最终 被线程池持有,最终造成了 Activity 的引用无法释放。
启动 ObservableSubscribeOn 的重写方法subscribeActual方法中,项线程池中提交了一个任务:
java
@Override
public void subscribeActual(final Observer<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<>(observer);
observer.onSubscribe(parent);
//scheduler 就是 Schedulers.io()
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
如何使用RxLifeCycle解决内存泄漏
解决内存泄漏要么使用 WeakReference ;要么在 onDestory 方法中 调实力isposable的dispose 取消订阅。而使用 RxLifeCycle 则可以自动的在某个生命周期方法中取消订阅。只需如下操作:
Activity 继承 RxAppCompatActivity
scala
public class MainActivity extends RxAppCompatActivity {
调用函数 compose(this.bindUntilEvent(ActivityEvent.STOP)) 取消订阅行为 绑定 Activity 生命周期事件就可以了。
less
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
//模拟耗时任务
Thread.sleep(1000 * 5);
emitter.onNext("hello world");
}
}).subscribeOn(Schedulers.io())//线程池执行耗时任务
.observeOn(AndroidSchedulers.mainThread())//主线程处理结果】
.compose(this.bindUntilEvent(ActivityEvent.STOP)) //关键代码
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
//结果回调
Log.i("tag", "accept " + s);
}
});
RxLifeCycle 解决内存泄漏的原理
原理其实上面已经说了,就是指定的生命周期事件中去取消订阅(dispose),下面我们看一下具体实现:
继承 RxAppCompatActivity 类,RxAppCompatActivity 中创建了 BehaviorSubject 对象,并在各个生命周期方法中发射对应的周期事件。
scala
public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
@Override
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@Override
protected void onStop() {
lifecycleSubject.onNext(ActivityEvent.STOP);
super.onStop();
}
再看 RxLifecycle.bindUnitlEvent 函数,我把调用链路收拢一下大概如上,subject 使用 filter 方法只接收传入的事件 上面传入的是 ActivityEvent.STOP。最后返回了 LifecyclerTransformer 的实例。
less
@CheckReturnValue
public static <T, R> LifecycleTransformer<T> bindUntilEvent(@Nonnull final Observable<R> lifecycle,
@Nonnull final R event) {
return new LifecycleTransformer<>(lifecycle.filter(new Predicate<R>() {
@Override
public boolean test(R lifecycleEvent) throws Exception {
return lifecycleEvent.equals(event);
}
})
);
}
再看 compose(:LifecycleTransformer) 函数,实际就是调用 LifecycleTransformer 的 apply 函数。最终调用到 upstream.takeUntil(observable);
其中 upstream 即我们原始的Obserable;observable 是我们RxAppcompatActivity中 lifecycle.filter 生成的 Observable 可以理解为生命周期的被观察者。所以当生命周期事件被触发后,原始的 Observable 会取消订阅(dispose).
takeUntil 函数会返回 ObservableTakeUntil 类的实例,典型的装饰模式。
swift
public final <R> Observable<R> compose(@NonNull ObservableTransformer<? super T, ? extends R> composer) {
return wrap(((ObservableTransformer<T, R>) Objects.requireNonNull(composer, "composer is null")).apply(this));
}
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.takeUntil(observable);
}
最后我们看一下 ObservableTakeUntil 类。同样重写了 subscribeActual 函数。other 属性就是上面的生命周期事件被观察者。 在其被观察者 OtherObserver 的 onNext 函数中,调用 DisposableHelper.dispose(this)。 到此就串联通了😄。
scala
public final class ObservableTakeUntil<T, U> extends AbstractObservableWithUpstream<T, T> {
final ObservableSource<? extends U> other;
public ObservableTakeUntil(ObservableSource<T> source, ObservableSource<? extends U> other) {
super(source);
this.other = other;
}
@Override
public void subscribeActual(Observer<? super T> child) {
TakeUntilMainObserver<T, U> parent = new TakeUntilMainObserver<>(child);
child.onSubscribe(parent);
//注册生命周期事件的监听
other.subscribe(parent.otherObserver);
source.subscribe(parent);
}
final class OtherObserver extends AtomicReference<Disposable> implements Observer<U> {
@Override
public void onNext(U t) {
//取消订阅
DisposableHelper.dispose(this);
otherComplete();
}
}
}
}
总结:
RxLifeCycle 是 RxJava3.0 中的辅助类。再深入理解后原理后值得一用,能帮方便快捷的处理内存泄漏。后面在接口开发模式 MVP, MVVM 做一些二次封装就更好了。