rxlifecycle2原理分析

应用场景

在这个RxJava已经火爆的不行的时代,如果你还没用那你就out了。用过RxJava的小伙伴都知道RxJava确实用的很爽,但是如果你处理的不好就会造成内存泄露,你可以自己处理(在页面销毁的时候取消订阅),当然这样写起来是不是很麻烦,很不爽,这就让rxlifecycle有了存在的价值。

阅读本文之前需要对RxJava有简单的了解

使用方法

这个比较简单直接参考官方介绍即可 RxLifecycle

简单示例

Android开发直接添加这三个依赖就行了

    compile 'com.trello.rxlifecycle2:rxlifecycle:2.2.0'
    compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.0'
    compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.0'

第三个可以不添加,在BaseActivity的生命周期里面自己绑定下就好了

1.指定生命周期断开(想在那断开就在那断开)

myObservable
    .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
    .subscribe();

2.让RxLifecycle确定断开时机(省心是省心,一般不这么用)

myObservable
    .compose(RxLifecycleAndroid.bindActivity(lifecycle))
    .subscribe();

就是这么简单! 就是这么简单! 就是这么简单!

分析原理之前先讲几个RxJava的操作符帮助理解

1.Observable

  • compose 其实就是一个可以对Observable本身转变的一个操作
  • filter 可以理解为一个过滤满足条件的数据才发射出去
  • takeUntil 发射来自原始Observable的数据,直到第二个Observable发射了一个数据
    或一个通知。如果第二个Observable发射了一项数据或者发射了一个终止通知, 原始Observable会停止发射并终止。
  • CombineLatest 当两个Observables中的任何一个发射了数据时,使用一个函数结合每个Observable发射的最近数据项,并且基于这个函数的结果发射数据。
  • take 只发射前面的N项数据
  • skip 跳过前面的N项数据
  • share 简单来说就是让 Observable 支持多订阅

2.Observer

  • onNext 相当于让Observer接受一条新数据

下面简单介绍下Subject以及BehaviorSubject

1.Subject

Subject可以看成是一个桥梁或者代理,在RxJava中它同时充当了ObserverObservable的角色。因为它是一个Observer,它可以订阅一个或多个Observable;又因为它是一个Observable,它可以转发它收到(Observe)的数据,也可以发射新的数据。

2.BehaviorSubject

BehaviorSubject继承自Subject,当观察者订阅BehaviorSubject时,它开始发射原始Observable最近发射的数据(如果此时还没有收到任何数据,它会发射一个默认值),然后继续发射其它任何来自原始Observable的数据。然而,如果原始的Observable因为发生了一个错误而终止,BehaviorSubject将不会发射任何数据,只是简单的向前传递这个错误通知。rxlifecycle2中就是用的它!!!

都介绍完了就开始分析rxlifecycle2的实现原理了以绑定Activity的生命周期为例(重点来了准备好姿势)

先上一段简单代码

public abstract class RxActivity extends Activity implements LifecycleProvider<ActivityEvent> {

    private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();

    @Override
    @NonNull
    @CheckResult
    public final Observable<ActivityEvent> lifecycle() {
        return lifecycleSubject.hide();
    }

    @Override
    @NonNull
    @CheckResult
    public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
        return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
    }

    @Override
    @NonNull
    @CheckResult
    public final <T> LifecycleTransformer<T> bindToLifecycle() {
        return RxLifecycleAndroid.bindActivity(lifecycleSubject);
    }

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

    @Override
    @CallSuper
    protected void onDestroy() {
        lifecycleSubject.onNext(ActivityEvent.DESTROY);
        super.onDestroy();
    }
}
    

首先RxActivity内部维护了个BehaviorSubject集Observable与Observer与一身,通过onNext()方法将Activity的各个生命周期与BehaviorSubject相结合,Activity每走一个生命周期BehaviorSubject就会接受到有个一个事件。

先来讲指定生命周期断开RxLifecycle.bindUntilEvent(lifecycle,ActivityEvent.DESTROY)

Observable
    .compose(RxLifecycleAndroid.bindActivity(lifecycle))

当原始Observable调用compose方法的时候传入的就是RxLifecycleAndroid.bindActivity(lifecycle)
我们来看下他的源码

public static <T, R> LifecycleTransformer<T> bindUntilEvent(@Nonnull final Observable<R> lifecycle,
                                                                @Nonnull final R event) {
        checkNotNull(lifecycle, "lifecycle == null");
        checkNotNull(event, "event == null");
        return bind(takeUntilEvent(lifecycle, event));
    }

    private static <R> Observable<R> takeUntilEvent(final Observable<R> lifecycle, final R event) {
        return lifecycle.filter(new Predicate<R>() {
            @Override
            public boolean test(R lifecycleEvent) throws Exception {
                return lifecycleEvent.equals(event);
            }
        });
    }

先做了两个空判断然后执行一个过滤,过滤的条件就是lifecycleEvent.equals(event)只有这个条件满足的时候才发出数据这个条件是的意思相信你已经看懂了其实就是RxLifecycle.bindUntilEvent(lifecycleSubject, event);这个方法传的Observable也就是Activity里面维护的BehaviorSubject发出的事件和你指定销毁的事件相等的时候才成立BehaviorSubject才能把事件传递出去。

继续往下看bind(takeUntilEvent(lifecycle, event))

public static <T, R> LifecycleTransformer<T> bind(@Nonnull final Observable<R> lifecycle) {
        return new LifecycleTransformer<>(lifecycle);
    }

其实就是new了个LifecycleTransformer并把lifecycle(也就是BehaviorSubject)通过构造方法传递进去了,最终把这个LifecycleTransformer一层层返回到原始Observable的compose方法中做参数。
我们在继续来看下这个LifecycleTransformer是什么

public final class LifecycleTransformer<T> implements ObservableTransformer<T, T>,
                                                      FlowableTransformer<T, T>,
                                                      SingleTransformer<T, T>,
                                                      MaybeTransformer<T, T>,
                                                      CompletableTransformer
{
    final Observable<?> observable;

    LifecycleTransformer(Observable<?> observable) {
        checkNotNull(observable, "observable == null");
        this.observable = observable;
    }

    @Override
    public ObservableSource<T> apply(Observable<T> upstream) {
        return upstream.takeUntil(observable);
    }

    @Override
    public Publisher<T> apply(Flowable<T> upstream) {
        return upstream.takeUntil(observable.toFlowable(BackpressureStrategy.LATEST));
    }

    @Override
    public SingleSource<T> apply(Single<T> upstream) {
        return upstream.takeUntil(observable.firstOrError());
    }

    @Override
    public MaybeSource<T> apply(Maybe<T> upstream) {
        return upstream.takeUntil(observable.firstElement());
    }

    @Override
    public CompletableSource apply(Completable upstream) {
        return Completable.ambArray(upstream, observable.flatMapCompletable(Functions.CANCEL_COMPLETABLE));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) { return true; }
        if (o == null || getClass() != o.getClass()) { return false; }

        LifecycleTransformer<?> that = (LifecycleTransformer<?>) o;

        return observable.equals(that.observable);
    }

    @Override
    public int hashCode() {
        return observable.hashCode();
    }

    @Override
    public String toString() {
        return "LifecycleTransformer{" +
            "observable=" + observable +
            '}';
    }
}

请看他实现了那些接口有没有看到ObservableTransformer,我们在回过头来看原始Observable的compose的源码

public final <R> Observable<R> compose(ObservableTransformer<? super T, ? extends R> composer) {
        return wrap(((ObservableTransformer<T, R>) ObjectHelper.requireNonNull(composer, "composer is null")).apply(this));
    }

发现没有compose最终执行的是ObservableTransformer的apply方法并把原始Observable通过参数传进去了,那实际上就是执行LifecycleTransformer的apply方法了,看看这个方法的实现

 @Override
    public ObservableSource<T> apply(Observable<T> upstream) {
        return upstream.takeUntil(observable);
    }

是不是恍然大悟,实际上就是执行upstream.takeUntil(observable),upstream就是原始的Observable而observable其实就是Activity里面维护的那个BehaviorSubject。

总结下就是原始的Observable通过takeUntil和BehaviorSubject绑定,当BehaviorSubject发出数据即Activity的生命周期走到和你指定销毁的事件一样时,原始的Observable就终止发射数据了

下面再来简单介绍下(RxLifecycleAndroid.bindActivity(lifecycle)原理差不多

来看下源码

// Figures out which corresponding next lifecycle event in which to unsubscribe, for Activities
    private static final Function<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE =
        new Function<ActivityEvent, ActivityEvent>() {
            @Override
            public ActivityEvent apply(ActivityEvent lastEvent) throws Exception {
                switch (lastEvent) {
                    case CREATE:
                        return ActivityEvent.DESTROY;
                    case START:
                        return ActivityEvent.STOP;
                    case RESUME:
                        return ActivityEvent.PAUSE;
                    case PAUSE:
                        return ActivityEvent.STOP;
                    case STOP:
                        return ActivityEvent.DESTROY;
                    case DESTROY:
                        throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it.");
                    default:
                        throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");
                }
            }
        };


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

bind方法传入的是lifecycle(BehaviorSubject)和 ACTIVITY_LIFECYCLE是一个Function
再看看bind源码

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

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

bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents))上面已经介绍过来这里就不在介绍了,重点就是LifecycleTransformer的apply方法执行upstream.takeUntil(observable)

ACTIVITY_LIFECYCLE 其实就是一个函数 Function ,把 Activity 的生命周期事件进行一下变换,CREATE 对应 DESTROY,RESUME 对应 PAUSE 等等。其含义就是 把当前的 Activity 生命周期转换成对应的需要被销毁的时候的生命周期。这个方法最终在lifecycle.take(1).map(correspondingEvents),中得到执行。而combineLatest方法就是把前面参数中的两个Observable基于第三个参数BiFunction整合后发射新的数据。lifecycleEvent.equals(bindUntilEvent)就是发射数据的条件。
lifecycle.take(1).map(correspondingEvents)相当指定销毁的的生命周期你在哪生命周期订阅的再参考ACTIVITY_LIFECYCLE 得到在要销毁的生命周期,最终还是和lifecycle(BehaviorSubject)发射的数据比较,如果两个一样说明Activity走到了该断开的生命周期了,upstream.takeUntil(observable)中的observable就要发通知告诉upstream(原始的Observable)该断开了。

本文參考
trello/RxLifecycle
BRUCEZZ’S CORNER
Rx中文文档

    原文作者:Vincent1118
    原文地址: https://www.jianshu.com/p/0d07fba84cb8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞