Android技术知识Android开发Android开发规范技巧

【RxJava】- RxLifecycle解决RxJava内存泄

2020-03-31  本文已影响0人  拔萝卜占坑

目录

【RxJava】- 创建操作符源码分析
【RxJava】- 变换操作符源码分析
【RxJava】- 过滤操作符源码分析
【RxJava】- 结合操作符源码分析
【RxJava】- 连接操作符源码分析

简介

在Activity中使用RxJava的时候,由于回调,RxJava持有Activity引用。当Activity销毁时,RxJava中的耗时任务还没有完成,如果这时候没有收到调用对应的dispose()方法,那么RxJava中持有的资源得不到释放,从而引起Activity的内存泄露。如果在Activity中手动调用,这样麻烦又不优雅,所以这时候可以使用RxLifecycle来解决。

使用

具体使用可以参考RxLifecycle,下面注意讲解RxLifecycle源码,带你一步步了解RxLifecycle实现的真相。

流程

分析之前,先用RxJava创建一个观察者模型任务。

Observable.create(emitter -> {}).compose(bindToLifecycle()).subscribe();

这里只分析bindToLifecycle()方法中的内容,其它都是RxJava中的操作符。

跟踪到

public static <T> LifecycleTransformer<T> bindActivity(@NonNull Observable<ActivityEvent> lifecycle) {
    return RxLifecycle.bind(lifecycle, ACTIVITY_LIFECYCLE);
}

下一步

public static <T, R> LifecycleTransformer<T> bind(@Nonnull Observable<R> lifecycle,
                                                  @Nonnull final Function<R, R> correspondingEvents) {
    ...
    return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));
}

takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents)方法构建一个新的Observable实例,即ObservableFilter对象。·

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);
}

参数lifecycle.share()

public final Observable<T> share() {return publish().refCount();}
public Observable<T> refCount() {
    return RxJavaPlugins.onAssembly(new ObservableRefCount<T>(onRefCount()));
}
    private ConnectableObservable<T> onRefCount() {
        if (this instanceof ObservablePublishClassic) {
            return RxJavaPlugins.onAssembly(
                    new ObservablePublishAlt<T>(((ObservablePublishClassic<T>)this).publishSource())
                   );
        }
        return this;
    }

最后调用bind(@Nonnull final Observable<R> lifecycle)返回一个持有上面创建的Observable实例的LifecycleTransformer对象。

发射Activity生命周期事件

发射Activity生命周期事件,封装RxLifecycle中的RxAppCompatActivity类里面(我继承的是RxAppCompatActivity)。比如onCreate:

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.lifecycleSubject.onNext(ActivityEvent.CREATE);
}

onNext方法

public void onNext(T t) {
    ...
    Object o = NotificationLite.next(t);
    setCurrent(o);
    for (BehaviorDisposable<T> bs : subscribers.get()) {
        bs.emitNext(o, index);
    }
}

subscribers中的值是一个BehaviorDisposable数组,在subscribeActual方法中进行添加。

protected void subscribeActual(Observer<? super T> observer) {
    BehaviorDisposable<T> bs = new BehaviorDisposable<T>(observer, this);
    if (add(bs)) {...};
    ...
}

emitNext方法中调用 test(value)来发射数据,如果已经有数据处于发射中,者将数据保存起来,然后返回。

public boolean test(Object o) {
    return cancelled || NotificationLite.accept(o, downstream);
}
public static <T> boolean accept(Object o, Observer<? super T> observer) {
    if (o == COMPLETE) {
        observer.onComplete();
        return true;
    } elseif (o instanceof ErrorNotification) {
        observer.onError(((ErrorNotification)o).e);
        return true;
    }
    observer.onNext((T)o);
    return false;
}

调用

Observable.create(emitter -> {}).compose(bindToLifecycle()).subscribe();

其它

// If you want pre-written support preference Fragments you can subclass as providers
implementation 'com.trello.rxlifecycle3:rxlifecycle-components-preference:3.1.0'
// If you want to use Android Lifecycle for providers
implementation 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle:3.1.0'

这两个是在其它情况下事情 ,具体自己看库里面的代码,很少。

上一篇 下一篇

猜你喜欢

热点阅读