近日阅读相关的代码,想起来我们在项目中使用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解除绑定。