Android 解决RxJava内存泄露之AutoDispose

Posted Rocky_ruan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 解决RxJava内存泄露之AutoDispose相关的知识,希望对你有一定的参考价值。

android 解决RxJava内存泄露之AutoDispose

一.概述
通常(尤其是在移动应用程序中),Rx 订阅需要停止以响应某些事件(例如,当 Activity#onStop() 在 Android 应用程序中执行时)。为了在 RxJava 2 中支持这种常见的场景,我们构建了 AutoDispose。
添加依赖:你可以根据GitHub上最新的版本

 //AutoDispose
    implementation \'com.uber.autodispose:autodispose:0.6.1\'
    implementation \'com.uber.autodispose:autodispose-android-archcomponents:0.6.1\'

二.使用

  Observable.interval(3, TimeUnit.SECONDS)
                .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))//最简单的使用就是这样
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.d("aaa", String.valueOf(aLong));
                    }
                });

那我们就需要重新拿说出来分析

as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))

1.我们看到我们传递了一个参数this
这个this代表的是什么了这个this直观的讲,就是Activity本身,当然它也可以是Fragment,这个参数对象只有一个要求,就是必须实现LifecycleOwner接口。
根据源码from方法可以看出:

public final class AndroidLifecycleScopeProvider implements LifecycleScopeProvider<Event> {
    private static final Function<Event, Event> DEFAULT_CORRESPONDING_EVENTS = new Function<Event, Event>() {
        public Event apply(Event lastEvent) throws Exception {
            switch(lastEvent) {
            case ON_CREATE:
                return Event.ON_DESTROY;
            case ON_START:
                return Event.ON_STOP;
            case ON_RESUME:
                return Event.ON_PAUSE;
            case ON_PAUSE:
                return Event.ON_STOP;
            case ON_STOP:
            case ON_DESTROY:
            default:
                throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent);
            }
        }
    };
    private final Function<Event, Event> boundaryResolver;
    private final LifecycleEventsObservable lifecycleObservable;
//在这里传递this,是实现了LifecycleOwner接口
    public static AndroidLifecycleScopeProvider from(LifecycleOwner owner) {
        return from(owner.getLifecycle());
    }

    public static AndroidLifecycleScopeProvider from(LifecycleOwner owner, Event untilEvent) {
        return from(owner.getLifecycle(), untilEvent);
    }
}

而Google Android官方的架构中都实现了这个
LifecycleOwner接口是Google Android官方架构组件:Lifecycle的一个重要组件,在v7包中,FragmentActivity和Fragment都实现了这个接口,实现了这个接口的对象都拥有生命周期(Lifecycle)。

这意味着,不仅是AppCompatActiviy(FragmentActivity的子类)和Fragment,只要是实现了LifecycleOwner的类,都可以作为参数传给AutoDispose,用以控制Observable和组件生命周期的绑定。
如果我们要封装的话要实现这个接口,封装起来传递
2.我们传递了this,即传递了要绑定的Activity和Fragment,我们怎么绑定生命周期了
我们可以看一下AndroidLifecycleScopeProvider的源码

public final class AndroidLifecycleScopeProvider
    implements LifecycleScopeProvider<Lifecycle.Event> {

  private static final Function<Lifecycle.Event, Lifecycle.Event> DEFAULT_CORRESPONDING_EVENTS =
      new Function<Lifecycle.Event, Lifecycle.Event>() {
        @Override public Lifecycle.Event apply(Lifecycle.Event lastEvent) throws Exception {
          switch (lastEvent) {
            case ON_CREATE:
              return Lifecycle.Event.ON_DESTROY;
            case ON_START:
              return Lifecycle.Event.ON_STOP;
            case ON_RESUME:
              return Lifecycle.Event.ON_PAUSE;
            case ON_PAUSE:
              return Lifecycle.Event.ON_STOP;
            case ON_STOP:
            case ON_DESTROY:
            default:
              throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent);
          }
        }
      };

也就是说,在我们的ObservableA订阅时,就已经知道了自己在Activity的哪个生命周期让AutoDispose内部自定义的ObservableB自动发射事件,ObservableA监听到这个事件时且未dispose,解除订阅避免内存泄漏。
这种和RxLifecycle的bindToLifecycle()方法差不多
这里我们也可以绑定生命周期方法,这样就和bindUntilEvent()的一样
例如:这样可以绑定我们需要的生命周期

   Observable.interval(3, TimeUnit.SECONDS)
                .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))//这种是当生命周期方法到onDestory()时候解除绑定
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.d("aaa", String.valueOf(aLong));
                    }
                });
                
     //结果,我按下home键回到桌面,没有走onDestroy()方法,故继续执行,没有解除绑定
aaa: 0
aaa: 1
aaa: 2
aaa: onPause()
aaa: 3
aaa: 4
aaa: 5
aaa: 6
 onDestory()

3.as方法执行后生成了一个什么?
as方法内部生成了一个AutoDisposeConverter对象,类似于compose,不同的是,Observable通过compose生成的对象还是Observable,但as方法生成的则是一个新的对象:

 public final <R> R as(@NonNull ObservableConverter<T, ? extends R> converter) {
        return ObjectHelper.requireNonNull(converter, "converter is null").apply(this);
    }

实际上,抛开复杂的细节,AutoDispose最终将原来的Observable,生成了一个新的AutoDisposeObservable对象, 在执行订阅时,也生成了一个新的AutoDisposingObserverImpl对象,在新的Observerble中处理逻辑,并将结果return

END:不负韶华,不负自己

以上是关于Android 解决RxJava内存泄露之AutoDispose的主要内容,如果未能解决你的问题,请参考以下文章

Android使用Rxlifecycle解决RxJava内存泄漏

Android :安卓学习笔记之事件内存泄露 的简单理解

内存泄露之常见问题解决--初级篇

一张图搞定-RxJava2的线程切换原理和内存泄露问题

一张图搞定-RxJava2的线程切换原理和内存泄露问题

内存泄露之常见问题解决--初级篇