优雅解决Rxjava内存泄漏问题autodispose源码详解

Rxjava想比大家基本都用过,它主要用了观察者模式,在使用的时候,例如在avtivity里面使用订阅了事件之后一定要在activity的onDestroy中取消订阅事件,不取消的话有可能存在内存泄漏的风险,例如被观察者里面的网络事件还没有处理完,用户直接点了后退。而autodispose框架就是专门用来优雅解决这种内存泄漏问题的方案。至于autodispose怎么用,大家直接看看github就可以了autodispose使用详解

ok,接下来直接写一个kotlin扩展方法来直接使用autodispose,如下:

fun <T> Observable<T>.autoDisposeSubscribe(scopeProvider: ScopeProvider, observer: Observer<T>) {
    this.subscribeOn(Schedulers.io())
        .unsubscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .`as`(AutoDispose.autoDisposable(scopeProvider))
        .subscribe(observer)
}

其中scopeProvider是通过 AndroidLifecycleScopeProvider.from(view.getViewLifecycle())拿到的,对autodispose的真正使用是在`as`(AutoDispose.autoDisposable(scopeProvider))这个方法,那么接下来,来看一下这个框架的真正实现原理是什么?先来看一下AutoDispose.autoDisposable方法的实现:

 public static <T> AutoDisposeConverter<T> autoDisposable(final ScopeProvider provider) {
    checkNotNull(provider, "provider == null");
    return autoDisposable(completableOf(provider));
  }

这个方法先检查传进来的provider不为null,然后对provider装饰一层RxjavaCompletabledeferf(defer 操作符与create、just、from等操作符一样,是创建类操作符,不过所有与该操作符相关的数据都是在订阅时才生效的。)方法,接下来看一下as操作符又包装了一层什么数据,最终调用apply方法

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

而它的真正实现类是AutoDisposeConverter类,也就是autoDisposable方法返回的,如下:

   public SingleSubscribeProxy<T> apply(final Single<T> upstream) {
        if (!AutoDisposePlugins.hideProxies) {
          return new AutoDisposeSingle<>(upstream, scope);
        }
        return new SingleSubscribeProxy<T>() {
          @Override
          public Disposable subscribe() {
            return new AutoDisposeSingle<>(upstream, scope).subscribe();
          }

          @Override
          public Disposable subscribe(Consumer<? super T> onSuccess) {
            return new AutoDisposeSingle<>(upstream, scope).subscribe(onSuccess);
          }

          @Override
          public Disposable subscribe(BiConsumer<? super T, ? super Throwable> biConsumer) {
            return new AutoDisposeSingle<>(upstream, scope).subscribe(biConsumer);
          }

          @Override
          public Disposable subscribe(
              Consumer<? super T> onSuccess, Consumer<? super Throwable> onError) {
            return new AutoDisposeSingle<>(upstream, scope).subscribe(onSuccess, onError);
          }

          @Override
          public void subscribe(SingleObserver<? super T> observer) {
            new AutoDisposeSingle<>(upstream, scope).subscribe(observer);
          }

          @Override
          public <E extends SingleObserver<? super T>> E subscribeWith(E observer) {
            return new AutoDisposeSingle<>(upstream, scope).subscribeWith(observer);
          }

          @Override
          public TestObserver<T> test() {
            TestObserver<T> observer = new TestObserver<>();
            subscribe(observer);
            return observer;
          }

          @Override
          public TestObserver<T> test(boolean dispose) {
            TestObserver<T> observer = new TestObserver<>();
            if (dispose) {
              observer.dispose();
            }
            subscribe(observer);
            return observer;
          }
        };
      }
省略若干行

最终调用的apply返回SingleSubscribeProxy类,也就是说最后的最外层订阅者是SingleSubscribeProxy,可以把Rxjava的操作符理解成装饰者模式,每一个操作符都是在原来的订阅者基础上装饰一层去做其他的事,比如线程切换,数据转换等等,那么最后调用订阅方法subscribe的就是SingleSubscribeProxy类,也就是调用了如下方法

  public void subscribe(SingleObserver<? super T> observer) {
            new AutoDisposeSingle<>(upstream, scope).subscribe(observer);
          }

也就是说最后调用subscribe方法的是AutoDisposeSingle订阅者,代码如下

 public final void subscribe(SingleObserver<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");

        observer = RxJavaPlugins.onSubscribe(this, observer);

        ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null SingleObserver. Please check the handler provided to RxJavaPlugins.setOnSingleSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

        try {
            subscribeActual(observer);
        } catch (NullPointerException ex) {
            throw ex;
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            NullPointerException npe = new NullPointerException("subscribeActual failed");
            npe.initCause(ex);
            throw npe;
        }
    }

接下来调用subscribeActual方法,实现方法如下:

  @Override
  protected void subscribeActual(SingleObserver<? super T> observer) {
    source.subscribe(new AutoDisposingSingleObserverImpl<>(scope, observer));
  }

 

现在又成被装饰者SingleObserveOn调用了订阅,此时的被观察者将AutoDisposingSingleObserverImpl装饰一下,Rxjava调用确实有点绕,可以理解为Rxjava首先从最外层的装饰者开始调用,直到最内层的装饰者被调用,最后处理完信息交给观察者处理,最内层的一般就是Observable被观察者,当它处理数据之前会先一层层调用观察者的onSubscribe方法,当它处理完数据之后会调一层层调用观察者的onNext的方法或onErroronComplete或onSuccess,当然这是可以自己控制的,至于retrofit封装的Rxjava的数据适配器大家可以自己研究学习一下,那么最终onSubscrice会执行到AutoDisposingSingleObserverImpl这个类,如下:

public void onSubscribe(final Disposable d) {
    DisposableCompletableObserver o =
        new DisposableCompletableObserver() {
          @Override
          public void onError(Throwable e) {
            scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
            AutoDisposingSingleObserverImpl.this.onError(e);
          }

          @Override
          public void onComplete() {
            scopeDisposable.lazySet(AutoDisposableHelper.DISPOSED);
            AutoDisposableHelper.dispose(mainDisposable);
          }
        };
    if (AutoDisposeEndConsumerHelper.setOnce(scopeDisposable, o, getClass())) {
      delegate.onSubscribe(this);
      scope.subscribe(o);
      AutoDisposeEndConsumerHelper.setOnce(mainDisposable, d, getClass());
    }
  }

此时会走到这个if判断里面

if (AutoDisposeEndConsumerHelper.setOnce(scopeDisposable, o, getClass())) {
      delegate.onSubscribe(this);
      scope.subscribe(o);
      AutoDisposeEndConsumerHelper.setOnce(mainDisposable, d, getClass());
    }

此处的scope就是它,也就是CompletableDefer,然后再调用它的调阅

 Completable.defer(
        () -> {
          try {
            return scopeProvider.requestScope();
          } catch (OutsideScopeException e) {
            Consumer<? super OutsideScopeException> handler =
                AutoDisposePlugins.getOutsideScopeHandler();
            if (handler != null) {
              handler.accept(e);
              return Completable.complete();
            } else {
              return Completable.error(e);
            }
          }
        });

订阅实现方法如下:

 protected void subscribeActual(CompletableObserver observer) {
        CompletableSource c;

        try {
            c = ObjectHelper.requireNonNull(completableSupplier.call(), "The completableSupplier returned a null CompletableSource");
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            EmptyDisposable.error(e, observer);
            return;
        }

        c.subscribe(observer);
    }

它内部又调用了包装类的call方法,然后通过返回的订阅者事件又调用了订阅,也就是说call方法最终是调用了scopeProvider.requestScope()返回订阅者,而scopeProvider的实现类是AndroidLifecycleScopeProvider,这确实比较绕,找起来容易找混,最终requestScope方法返回如下:

  public CompletableSource requestScope() {
    return LifecycleScopes.resolveScopeFromLifecycle(this);
  }

这个方法最终会调用到LifecycleScopes 的resolveScopeFromLifecycle方法

 public static <E> CompletableSource resolveScopeFromLifecycle(
      Observable<E> lifecycle, final E endEvent, @Nullable final Comparator<E> comparator) {
    Predicate<E> equalityPredicate;
    if (comparator != null) {
      equalityPredicate = e -> comparator.compare(e, endEvent) >= 0;
    } else {
      equalityPredicate = e -> e.equals(endEvent);
    }
    return lifecycle.skip(1).takeUntil(equalityPredicate).ignoreElements();
  }

其中lifecycle的实现类是LifecycleEventsObservable,这里判断了activity事件的生命周期并将ON_DESTROY的生命周期信号作为takeUntil的判断信号用来是否回调最后的观察者对象,通俗的讲就是如果当前activity或fragment的生命周期走到尽头,那么Rxjava的被观察者处理完事件后就没有必要通知观察者了。

看到这里,autodispose的流程原理已经理清,通俗的讲就是在Rxjava的调用链的通知环节中引入 LifecycleEventsObservable订阅者,并在订阅的时候绑定组件(可以是activity、fragment)的生命周期,也就是下面的代码:

protected void subscribeActual(Observer<? super Event> observer) {
    ArchLifecycleObserver archObserver =
        new ArchLifecycleObserver(lifecycle, observer, eventsObservable);
    observer.onSubscribe(archObserver);
    if (!isMainThread()) {
      observer.onError(
          new IllegalStateException("Lifecycles can only be bound to on the main thread!"));
      return;
    }
    lifecycle.addObserver(archObserver);
    if (archObserver.isDisposed()) {
      lifecycle.removeObserver(archObserver);
    }
  }

代码 lifecycle.addObserver(archObserver)就可以监听到组件生命周期,也就是ArchLifecycleObserver类的onStateChange方法

   @OnLifecycleEvent(Event.ON_ANY)
    void onStateChange(@SuppressWarnings("unused") LifecycleOwner owner, Event event) {
      if (!isDisposed()) {
        if (!(event == ON_CREATE && eventsObservable.getValue() == event)) {
          // Due to the INITIALIZED->ON_CREATE mapping trick we do in backfill(),
          // we fire this conditionally to avoid duplicate CREATE events.
          eventsObservable.onNext(event);
        }
        observer.onNext(event);
      }
    }
  }

每次生命周期改变的时候eventsObservable用来记录生命周期状态,observer用来处理生命周期是否该结束当前引用链(是否调用dispose方法),其中observer可以理解为包裹了AutoDisposingObserverImpl,AutoDisposingObserverImpl又包裹了真正的观察者回调,而AutoDisposingObserverImpl又被lifecycle.skip(1).takeUntil(equalityPredicate).ignoreElements()方法装饰了几次,那么每次onNext的方法都会走

ObservableSkip->ObservableTakeUntilPredicate->ObservableIgnoreElementsCompletable->AutoDisposingObserverImpl->最终的观察者回调,那么这条链的任何一个环节只要加入回调暂停的话,那么真正的观察者的链就会停止,而被处理的这条链就是TakeUntilPredicateObserver处理的,如下代码:
  public void onNext(T t) {
            if (!done) {
                downstream.onNext(t);
                boolean b;
                try {
                    b = predicate.test(t);
                } catch (Throwable e) {
                    Exceptions.throwIfFatal(e);
                    upstream.dispose();
                    onError(e);
                    return;
                }
                if (b) {
                    done = true;
                    upstream.dispose();
                    downstream.onComplete();
                }
            }
        }

每次事件过来后将会判断当前组件的生命周期是否到达最后,如果到达最后done为true,直接把上游的upstream中断调用dispose,之后调用ArchLifecycleObserver的onDispose方法,用来取消监听生命周期,既然生命周期已经结束就没有必要监听了

  protected void onDispose() {
      lifecycle.removeObserver(this);
    }

 

下游直接调用onComplete证明此次事件结束,当被观察者在子线程处理任务时就不会再向外层分发,从而起到阻断事件的作用,而下面的代码也在次结束,不会朝真正的观察者传递

  public void onError(Throwable t) {
            if (!done) {
                done = true;
                downstream.onError(t);
            } else {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public void onComplete() {
            if (!done) {
                done = true;
                downstream.onComplete();
            }
        }

不得不说autodispose设计的非常巧妙,跟着引用链看源码很有可能转晕

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值