RxLifecycle源码解读—如何绑定生命周期

近日阅读相关的代码,想起来我们在项目中使用Rxjava编码过程使用到了bindToLifecycle来绑定一个Rxjava的Observable的生命周期,时间长忘记了内部是如何实现的,进而阅读到了RxLifecycle的源码,复习一下做如下记录。

具体RxFragment中是如何实现 bindToLifecycle 方法的?先查阅代码如下:

public abstract class RxFragment extends Fragment implements LifecycleProvider<FragmentEvent> {

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

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

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

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

    @Override
    public void onAttach(android.app.Activity activity) {
        super.onAttach(activity);
        lifecycleSubject.onNext(FragmentEvent.ATTACH);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        lifecycleSubject.onNext(FragmentEvent.CREATE);
    }

    ......

}

查看RxFrament的代码,大致如上,首先定义了一个全局变量 BehaviorSubject,在onAttach、onCreate、onViewCreated等生命周期方法中调用了BehaviorSubject 的next方法发送数据。

如:lifecycleSubject.onNext(FragmentEvent.START);

最后在调用bindToLeftcycle方法的时候处理绑定:

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


public static <T> LifecycleTransformer<T> bindFragment(@NonNull final     
    Observable<FragmentEvent> lifecycle) {
        return bind(lifecycle, FRAGMENT_LIFECYCLE);
    }

这里用到了一个 FRAGMENT_LIFECYCLE,他的代码如下:

private static final Function<FragmentEvent, FragmentEvent> FRAGMENT_LIFECYCLE =
        new Function<FragmentEvent, FragmentEvent>() {
            @Override
            public FragmentEvent apply(FragmentEvent lastEvent) throws Exception {
                switch (lastEvent) {
                    case ATTACH:
                        return FragmentEvent.DETACH;
                    case CREATE:
                        return FragmentEvent.DESTROY;
                    case CREATE_VIEW:
                        return FragmentEvent.DESTROY_VIEW;
                    case START:
                        return FragmentEvent.STOP;
                    case RESUME:
                        return FragmentEvent.PAUSE;
                    case PAUSE:
                        return FragmentEvent.STOP;
                    case STOP:
                        return FragmentEvent.DESTROY_VIEW;
                    case DESTROY_VIEW:
                        return FragmentEvent.DESTROY;
                    case DESTROY:
                        return FragmentEvent.DETACH;
                    case DETACH:
                        throw new OutsideLifecycleException("Cannot bind to Fragment lifecycle when outside of it.");
                    default:
                        throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented");
                }
            }
        };

实际上是对生命周期方法进行了转换,比如attach对应了解除的deatch,start对应了stop,其他的生命周期的对应关系也可在上述代码中查看到。

如果是Activity中则 RxAppCompatActivity中对应关系如下:

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

Activity对应关系有如下几种

  • onCreate -> onDestory
  • onStart -> onStop
  • onResume -> onPause
  • onPause -> onStop
  • onStop ->  onDestory

我们看下 RxLifecycle 中的一些源码:

    @Nonnull
    @CheckReturnValue
    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);
            }
        });
    }

绑定的方法bindUntilEvent中调用RxLifecycle.bindUntilEvent(lifecycleSubject, event)传入了创建的subject,进入具体方法中,可以看到调用了takeUntilEvent方法。

进入到takeUntilEvent方法,方法中对subject使用filter方法过滤Event,即返回的新的observable只接收传入的event。

回到bindUntilEvent中调用的bind方法,他返回了一个 LifecycleTransformer 对象。

 @Nonnull
    @CheckReturnValue
    public static <T, R> LifecycleTransformer<T> bind(@Nonnull final Observable<R> lifecycle) {
        return new LifecycleTransformer<>(lifecycle);
    }
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());


    ......

}

可以看到LifecycleTransformer中实现了RxJava中的各个Transformer 接口,在其apply方法中调用了 upstream.takeUntil(observable) ,其中的upstream就是我们上游发送的数据,通过takeUntil操作符进行处理。

takeUntil操作符接受一个参数也是observable,当参数的observable发送数据的时候,上游就会停止发送数据,因此而解除上游的绑定。(具体可查看takeUntil操作符)

将上面的代码结合则大致如下:

upstream.takeUntil(lifecycleSubject.filter(new Predicate<R>() {
            @Override
            public boolean test(R lifecycleEvent) throws Exception {
                return lifecycleEvent.equals(event);
            }
        });

所以,以bindUntilEvent(ActivityEvent.DESTORY)为例,当Activity执行到onDestory时,lifecycleSubject发射ActivityEvent.DESTORY事件,此时upstream即取消了订阅,实现了生命周期的绑定。

bindToLifecycle 方法

接着看下bindToLifecycle方法如何实现生命周期的绑定:

调用了 

public static <T> LifecycleTransformer<T> bindFragment(@NonNull final Observable<FragmentEvent> lifecycle) {
        return bind(lifecycle, FRAGMENT_LIFECYCLE);
    }

接着调用了bind方法

    @Nonnull
    @CheckReturnValue
    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返回一个Observable对象。takeUntilCorrespondingEvent的参数是  lifecycle和correspondingEvents.

(注意这里参数使用的lifecycle.share()操作符,本质上对数据没有做处理,从字面意义看就是可以共享这个数据源)

takeUntilCorrespondingEvent方法使用combineLatest操作符结合两个observable
先看lifecycle.take(1).map(correspondingEvent),

take(1)表示取第一个元素,再进行map操作,此处传入的参数是FRAGMENT_LIFECYCLE,从前面的分析中我们知道 FRAGMENT_LIFECYCLE是对应了Frament生命周期的转换。

所以observable.take(1).map方法发射元素是当前Frament周期所对应的解除周期。

再看observable.skip(1)即跳过1个元素,即跳过当前最后一次的周期

然后用combineLaster结合两个obserable,这里对Event进行equal操作,返回boolean值。

这里使用的Observable.combineLatest是RxJava提供的一个操作符,它接受两个或以上的Observable和一个FuncX闭包。当传入的Observable中任意的一个发射数据时,combineLatest将每个Observable的最近值(Lastest)联合起来(combine)传给FuncX闭包进行处理.

再结合实际说明,当upstream在onCreate后订阅,observable.take(1).map发射元素为FragmentEvent.DESTORY,之后Fragment执行到onPause,事件为 FragmentEvent.PAUSE,执行合并操作.

其中  lifecycleEvent.equals(bindUntilEvent)语句返回了false。

后面还有filter操作,过滤掉了false,所以不会接触绑定,当Fragment生命周期到onDestory时,发射FragmentEvent.DESTORY,这时候upstream即会解除订阅,实现生命周期自动绑定.

对于Activity的 bindToLifecycle 方法,实际和Fragment一样:

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

只是替换了bind的参数为 ACTIVITY_LIFECYCLE。

因此,我们可以由上得知,RxJava绑定生命周期的原理是:

通过一个 BehaviorSubject 在生命周期变化的时候发送数据(生命周期),在调用了bindToLifeCycle方法时对绑定的生命周期进行转换,判断对应的生命周期中是否需要解除绑定,内部通过 一个 LifecycleTransformer 在apply方法中通过 upstream.takeUntil(observable) 进行处理,当takeUntil操作符中传入的参数发送数据时则上游的Observable解除绑定。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值