Rxjava解除订阅②:AutoDispose

Rxjava解除订阅三部曲:

  • Rxjava解除订阅①:自带方式和RxLifeCycle

  • Rxjava解除订阅②:AutoDispose

  • Rxjava解除订阅③:RxLife

前言

上一篇介绍了Rxjava解除订阅①:自带方式和RxLifeCycle,并且在结尾也透漏了可以解决RxLifeCycle的弊端的方法,那就是AutoDispose。其实AutoDispose大部分也是借鉴RxLifeCycle的经验,很多地方都比较相似,所以源码也比较容易阅读。github地址:AutoDispose

使用

引入:
androidX以下的版本只支持到0.8.0,android x 并且使用rxjava2,可以使用1.x版本;使用rxjava3的话可以升级到2.x版本。这里以1.3版本为主:

def autoDispose = "1.3.0"
dependencies {
    implementation "com.uber.autodispose:autodispose:${autoDispose}"
    implementation "com.uber.autodispose:autodispose-android-archcomponents:${autoDispose}"
}

应用起来也很简单:

Observable.interval(0, 2, TimeUnit.SECONDS)
                .map(aLong -> {
                    Log.d(TAG, "aLong:" + aLong);
                    return aLong == 4;
                })
               // .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))  //指定解绑生命周期
                .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))  // 自动识别生命周期解绑
                .subscribe(aBoolean -> Log.d(TAG, "aBoolean:" + aBoolean));

使用as操作符,传递AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this))方法即可。跟RxLifeCycle一样,除了上面这个自动识别生命周期来解绑之外,也提供了AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY))在指定的生命周期解绑操作。

as操作符是什么呢?是将Observable转成一个新的对象,跟compose不同的地方在于,compose是将Observable生成的对象还是Observable。

原理

1.this是什么?

RxLifeCycle类似,也是传递当前Activity的this进去,不同的是这个this并不是Activity本身,而是LifecycleOwner。关于LifecycleOwner大家自行搜索一下,是google提供的一个生命周期管理的类。

2.生命周期是如何绑定的?

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

知道了this,下一步就是看生命周期是如何绑定,进而在合适的生命周期解绑rxjava。AutoDispose.autoDisposable()传递进的是一个ScopeProvider,翻译中文可以认为是一种能力的提供者,那我们传递的AndroidLifecycleScopeProvider.from(this)返回的就是一个AndroidLifecycleScopeProvider,字面意思就是说android生命周期能力提供者。

那么这俩方法的作用就知晓了:AutoDispose.autoDisposable()是进行生命周期的解绑方法,而AndroidLifecycleScopeProvider.from(this)是提供对应的生命周期方法。

AutoDispose.autoDisposable()比较简单:

public static  AutoDisposeConverter autoDisposable(final ScopeProvider provider) {
    checkNotNull(provider, "provider == null");
    return autoDisposable(
        Completable.defer(
            () -> {
              try {
                return provider.requestScope();// 核心方法:最终调用ScopeProvider 的requestScope()
              } catch (OutsideScopeException e) {
                ...
              }
            }));
  }

这里用到了defer操作符,没啥特别的含义,可以简单的理解为懒加载,只有订阅关系成立时才会触发这个方法。

而return 的autoDisposable()方法则是返回对应的ObservableConverter。这也是因为我们的订阅关系是从Observable开始的,如果是Flowable,那么对应返回的就是FlowableConverter。而autoDisposable()内部实现了多个订阅关系的Converter,无论哪种订阅关系,都可以实现自动解绑。

最终核心的方法是调用了provider.requestScope()
一路追踪源码:

public static  CompletableSource resolveScopeFromLifecycle( final LifecycleScopeProvider provider, final boolean checkEndBoundary)
      throws OutsideScopeException {
    E lastEvent = provider.peekLifecycle();
    CorrespondingEventsFunction eventsFunction = provider.correspondingEvents();
    if (lastEvent == null) {
      throw new LifecycleNotStartedException();
    }
    E endEvent;
    try {
      endEvent = eventsFunction.apply(lastEvent);// 获取当前生命周期
    } catch (Exception e) {
      ...
    }
    return resolveScopeFromLifecycle(provider.lifecycle(), endEvent);
  }

到这,算是知晓了生命周期是从何而来,CorrespondingEventsFunction会提供给我们最后的一个生命周期方法,无论是自动识别生命周期还是指定生命周期解绑,最终都是通过CorrespondingEventsFunction得来的。为何要这么说呢?让我们回到from方法来看:

// 在指定生命周期解除绑定
public static AndroidLifecycleScopeProvider from(LifecycleOwner owner, Lifecycle.Event untilEvent) {
    return from(owner.getLifecycle(), untilEvent);
  }
// 自动解除绑定
public static AndroidLifecycleScopeProvider from(Lifecycle lifecycle) {
    return from(lifecycle, DEFAULT_CORRESPONDING_EVENTS);
  }

而自动解除绑定的生命周期判定是DEFAULT_CORRESPONDING_EVENTS是这样的:

private static final CorrespondingEventsFunction DEFAULT_CORRESPONDING_EVENTS =
      lastEvent -> {
        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);
        }
      };

这个地方可以看到DEFAULT_CORRESPONDING_EVENTS其实是CorrespondingEventsFunction的一个实例,而实现的内容是不是也很眼熟呢?这块跟RxLifeCycle一样,自动选择合适生命周期。

再往里走看看指定生命周期的from方法是啥:

public static AndroidLifecycleScopeProvider from(
      Lifecycle lifecycle, Lifecycle.Event untilEvent) {
    return from(lifecycle, new UntilEventFunction(untilEvent));
  }
//UntilEventFunction是CorrespondingEventsFunction一个具体实现类
private static class UntilEventFunction implements CorrespondingEventsFunction {
    private final Lifecycle.Event untilEvent;

    UntilEventFunction(Lifecycle.Event untilEvent) {
      this.untilEvent = untilEvent;
    }

    @Override
    public Lifecycle.Event apply(Lifecycle.Event event) throws OutsideScopeException {
      return untilEvent;// 返回指定的生命周期
    }
  }

UntilEventFunctionCorrespondingEventsFunction一个具体实现类,最终apply方法也是返回了我们指定的那个生命周期。
转了一圈到此为止,我们也算是了解了生命周期是如何获取的。那么怎么解绑呢?其实这块内容跟RxLifeCycle就非常相似了:
我们继续追踪resolveScopeFromLifecycle方法到最后实现:

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

是不是跟RxLifeCycle的最终核心方法非常相似,也是用的takeUntil操作符,在指定的生命周期内,打断上层数据流,从而实现自动解绑,避免内存泄漏。

这里简单的说下操作的过程:

  • 首先skip(1)的意思是说,忽略发送的第一个生命周期,因为获取到的第一个生命周期往往都是发送订阅关系的这个生命周期,比如在onCreate中绑定,那么剩下的生命周期就是onStart,onResume,onPause,onDestory了。
  • 再然后takeUntil(equalityPredicate),这个操作符比较简单,通过对比判断当前生命周期和指定生命周期是否一致,一致则打断上面的数据流,实现解绑。
  • 最终ignoreElements忽略不执行onNext方法,只执行onComplete或者onError。

到此为止,解绑的源码也就分析完了。

对比RxLifeCycle

AutoDispose中很多都是借鉴RxLifeCycle,而设计上有些出入:

  • 1.RxLifeCycle使用需要实现RxAppCompatActivity或者RxFragment,对于商业应用来说,随随便便改动基础类是很危险的事情,从设计的角度上来讲:组合的灵活度多数情况下更优于继承。而RxLifecycle在父类中声明了一个PublishSubject,用来发射生命周期事件,这是导致其局限性的原因之一。

  • 2.在绑定生命周期的设计上,两者也截然不同。RxLifeCycle需要继承基类,然后从基类中获取生命周期发射到底层,限制了使用场景,对于MVP架构来说,Activity和Fragment作为V层负责是ui更新,具体逻辑实现要在P层实现,RxLifeCycle无法做到在P层自动解绑。而AutoDispose是基于google的LifecycleOwner实现的,这就大大增加了可扩展性,也就意味着MVP架构的P层实际上也可以直接实现自动解绑操作了。

  • 3.同上因为RxLifeCycle限制使用场景,在我们自定义View中很难应用自动解绑,而AutoDispose则可以解决这个问题,并且也提供了对应ViewScopeProvider,使用跟在Activity中一样,会自动在Detach时解绑。

MVP架构P层自动解绑

要完成P层自动解绑,需要了解几个类:LifecycleOwnerLifecycleLifecycleObserver,具体百度吧。
P层接口继承LifecycleObserver

public interface IPresenter extends LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(LifecycleOwner owner);

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy(LifecycleOwner owner);
}

P层实现:

public class BasePresenter implements IPresenter {
    private LifecycleOwner mLifecycleOwner;

    @Override
    public void onCreate(LifecycleOwner owner) {
        this.mLifecycleOwner = owner;
    }

    protected  AutoDisposeConverter bindLifecycle() {
        if (mLifecycleOwner == null) {
            throw new NullPointerException("未获取LifecycleOwner");
        }
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(mLifecycleOwner));
    }

    @Override
    public void onDestroy(LifecycleOwner owner) {
    }
}

最后在Activity或者Fragment注册订阅

public class Main2Activity extends AppCompatActivity {
    private BasePresenter mPresenter = new BasePresenter();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
       getLifecycle().addObserver(mPresenter);
}

完成三步,就可以实现P层生命周期监听以及自动解绑操作了。

结语

经过对比可看出AutoDispose在设计上更优于RxLifeCycle,无论是扩展性还是解耦上都比RxLifeCycle要强一些。而对于我们使用者来说,只要能够满足需求,就是好库。

下章预告:Rxjava解除订阅③:RxLife,敬请期待...

你可能感兴趣的:(Rxjava解除订阅②:AutoDispose)