博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
rxjava : RxLifeCycle解析
阅读量:203 次
发布时间:2019-02-28

本文共 11288 字,大约阅读时间需要 37 分钟。

参考:

RxLifeCycle 官方demo:

//Note:Activity需要继承RxAppCompatActivity,fragment需要继承RxFragment//    implementation 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'//    // If you want to bind to Android-specific lifecycles//    implementation 'com.trello.rxlifecycle3:rxlifecycle-android:3.1.0'//    // If you want pre-written Activities and Fragments you can subclass as providers//    implementation 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'public class Activity1 extends RxAppCompatActivity {	//RxAppCompatActivity    private static final String TAG = "RxLifecycleAndroid";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG, "onCreate()");        setContentView(R.layout.activity_main);        // Specifically bind this until onPause()        Disposable disposable = Observable.interval(1, TimeUnit.SECONDS)                .doOnDispose(new Action() {                    @Override                    public void run() throws Exception {                        Log.i(TAG,                         "Unsubscribing subscription from onCreate()");                    }                })                //在activity onPause的时候取消订阅 : 【手动】指定结束时间                .compose(this.
bindUntilEvent(ActivityEvent.PAUSE)) .subscribe(new Consumer
() { @Override public void accept(Long num) throws Exception { Log.i(TAG, "Started in onCreate(), running until onPause(): " + num); } }); } @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart()"); // Using automatic unsubscription, //this should determine that the correct time to // unsubscribe is onStop (the opposite of onStart). //使用自动退订,这应该确定//退订的正确时间是onStop(与onStart相反)。 Disposable disposable = Observable.interval(1, TimeUnit.SECONDS) .doOnDispose(new Action() { @Override public void run() throws Exception { Log.i(TAG, "Unsubscribing subscription from onStart()"); } }) //bindToLifecycle的自动取消订阅示例,因为是在onStart的时候调用, //所以在onStop的时候自动取消订阅 //自动设定解除订阅的时间: //(ps:比如你是在onStart时候订阅,则自动会在onPause时候解除, //如果在onCreate时候订阅,则会自动在onDestory时候解除) //【自动】识别结束时间: 根据当前的生命周期 .compose(this.
bindToLifecycle()) .subscribe(new Consumer
() { @Override public void accept(Long num) throws Exception { Log.i(TAG, "Started in onStart(), running until in onStop(): " + num); } }); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume()"); // `this.
` is necessary if you're compiling on JDK7 or below. // // If you're using JDK8+, then you can safely remove it. Disposable disposable = Observable.interval(1, TimeUnit.SECONDS) .doOnDispose(new Action() { @Override public void run() throws Exception { Log.i(TAG, "Unsubscribing subscription from onResume()"); } }) //在activity onDestroy的时候取消订阅 ,【手动】指定结束时间 .compose(this.
bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Consumer
() { @Override public void accept(Long num) throws Exception { Log.i(TAG, "Started in onResume(), running until in onDestroy(): " + num); } }); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause()"); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy()"); }}

RxAppCompatActivity 源码

public abstract class RxAppCompatActivity extends AppCompatActivity 								implements LifecycleProvider
{ //创建一个BehaviorSubject,用来做takeUntil中的第二个Observable, //让其在核实的生命周期发送信息。 private final BehaviorSubject
lifecycleSubject = BehaviorSubject.create(); public RxAppCompatActivity() { } @ContentView public RxAppCompatActivity(@LayoutRes int contentLayoutId) { super(contentLayoutId); } @NonNull @CheckResult public final Observable
lifecycle() { return this.lifecycleSubject.hide(); //使用hide()方法把这个subject暴露出去 } @NonNull @CheckResult public final
LifecycleTransformer
bindUntilEvent( @NonNull ActivityEvent event) { //手动解除订阅 return RxLifecycle.bindUntilEvent(this.lifecycleSubject, event); } @NonNull @CheckResult public final
LifecycleTransformer
bindToLifecycle() { //自动解除订阅:自动识别生命周期 return RxLifecycleAndroid.bindActivity(this.lifecycleSubject); } @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //在onCreate时候发送信息 this.lifecycleSubject.onNext(ActivityEvent.CREATE); } @CallSuper protected void onStart() { super.onStart(); //在onStart时候发送信息 this.lifecycleSubject.onNext(ActivityEvent.START); } @CallSuper protected void onResume() { super.onResume(); //在onResume时候发送信息 this.lifecycleSubject.onNext(ActivityEvent.RESUME); } @CallSuper protected void onPause() { //在onPause时候发送信息 this.lifecycleSubject.onNext(ActivityEvent.PAUSE); super.onPause(); } @CallSuper protected void onStop() { //在onStop时候发送信息 this.lifecycleSubject.onNext(ActivityEvent.STOP); super.onStop(); } @CallSuper protected void onDestroy() { //在onDestroy时候发送信息 this.lifecycleSubject.onNext(ActivityEvent.DESTROY); super.onDestroy(); }}

注意:

在onCreate , onStart , onResume的时候,都是先调用super.XXX, 然后再用subject 发送相关Event;

但是在 onPause , onStop , onDestory 里面却是先用subject 发送相关Event,然后再调用super.XXXX。

为啥会有这个区别。

因为一般取消订阅都是在onPause,onStop,onDestory情形下,所以优先先取消订阅,再去执行系统自己的操作。

比如onDestory,先去取消订阅,再去执行super.onDestory方法。

手动解除订阅

手动解除订阅会调用 bindUntilEvent 等一系列方法:

//将给定的源绑定到生命周期。 当生命周期事件发生时,源将停止发出任何通知。 //lifecycle : 生命周期序列//event : 应该终止来自源的通知的事件public static 
LifecycleTransformer
bindUntilEvent( @Nonnull final Observable
lifecycle, @Nonnull final R event) { checkNotNull(lifecycle, "lifecycle == null"); checkNotNull(event, "event == null"); return bind(takeUntilEvent(lifecycle, event));}//只监听指定的生命周期private static
Observable
takeUntilEvent( final Observable
lifecycle, final R event) { return lifecycle.filter(new Predicate
() { @Override public boolean test(R lifecycleEvent) throws Exception { return lifecycleEvent.equals(event); } });}//将给定的源绑定到生命周期。 //此帮助程序会自动(根据生命周期序列本身)确定源应该何时停止发射物品。//请注意,对于此方法,它假定给定生命周期发出的any事件表示生命周期已结束。public static
LifecycleTransformer
bind( @Nonnull final Observable
lifecycle) { return new LifecycleTransformer<>(lifecycle);}

LifecycleTransformer 实现的apply方法:

//observable : 生命周期LifecycleTransformer(Observable
observable) { checkNotNull(observable, "observable == null"); this.observable = observable;}//upstream : 我们自己的observable@Overridepublic ObservableSource
apply(Observable
upstream) { //当observable发射数据,upstream就会停止 return upstream.takeUntil(observable);}

总结:

lifecycleSubject 会发送各个生命周期,并监听指定的生命周期,当到达指定的时间,便通过takeUntil取消我们自己的observable任务

自动解除订阅:

public final 
LifecycleTransformer
bindToLifecycle() { return RxLifecycleAndroid.bindActivity(this.lifecycleSubject);}

这里 bindToLifecycle() 实质调用:

RxLifecycleAndroid.bindActivity(this.lifecycleSubject);

public static 
LifecycleTransformer
bindActivity( @NonNull Observable
lifecycle) { return RxLifecycle.bind(lifecycle, ACTIVITY_LIFECYCLE);}private static final Function
ACTIVITY_LIFECYCLE = new Function
() { 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"); } }};

这里 bindActivity() 实质调用:

RxLifecycle.bind(lifecycle, ACTIVITY_LIFECYCLE)

//将给定的源绑定到生命周期。//此方法(根据生命周期序列本身)确定源应该何时停止发射物品。//它使用提供的相应事件函数确定何时取消订阅。 //请注意,这是该库的高级用法,通常应仅在您真正了解给定生命周期正在做什么时才使用。//lifecycle : 生命周期序列//correspondingEvents : 一个Function,告知源何时取消订阅public static 
LifecycleTransformer
bind( @Nonnull Observable
lifecycle, @Nonnull final Function
correspondingEvents) { checkNotNull(lifecycle, "lifecycle == null"); checkNotNull(correspondingEvents, "correspondingEvents == null"); return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));}

这里 bind() 实质调用:

bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents))

private static 
Observable
takeUntilCorrespondingEvent( final Observable
lifecycle, final Function
correspondingEvents) { return Observable.combineLatest( //第一个Observable:记录在哪个生命周期去取消订阅。 lifecycle.take(1).map(correspondingEvents), //第二个Observable:在不同生命周期发送不同事件, //当二个事件和第一个事件相同时候就说明要取消订阅了。 //但是我们第一次要跳过,因为第一个事件是在订阅时候发生的 。 lifecycle.skip(1), new BiFunction
() { @Override public Boolean apply(R bindUntilEvent, R lifecycleEvent) throws Exception { return lifecycleEvent.equals(bindUntilEvent); } }) .onErrorReturn(Functions.RESUME_FUNCTION) .filter(Functions.SHOULD_COMPLETE);}//这里的bind方法和手动解除订阅是一样的:public static
LifecycleTransformer
bind( @Nonnull final Observable
lifecycle) { return new LifecycleTransformer<>(lifecycle);}

来看Observable.combineLatest,这个操作符接收三个参数。

第一个参数:取BehaviorSubject发射的数据中的第一个,然后转换成对应的生命周期。例如在onStart()中调用了bindToLifecycle,take(1)后的数据是ActivityEvent.START,经过map(),返回ActivityEvent.STOP。

第二个参数:从BehaviorSubject发射的数据中经过.skip(1)操作符,过滤掉第一个数据。例如在onStart()中调用了bindToLifecycle,在后续的生命周期中会收到,ActivityEvent.RESUME、ActivityEvent.PAUSE、ActivityEvent.STOP、ActivityEvent.DESTROY

第三个参数:作用是combineFunction,把前两个参数最近发射的数据按照规则进行合并。规则是比对两次事件是否相等,然后合并后数据返回Boolean结果。比如params2发射ActivityEvent.RESUME的时候,和params1发射的ActivityEvent.STOP进行比对,返回false结果;params2发射ActivityEvent.STOP的时候,和params1发射的ActivityEvent.STOP进行比对,返回true结果。

通过combineLatest把二个绑定一起,这时候就会在指定的生命周期时候就会发送true,其余时候发送false,

最后配合filter操作符,只有在true的时候才能发送即可。
这样最终通过takeUntil再把我们的Observable绑定在一起,
然后这时候这里发送true的时候,我们的Observable就会取消订阅了。

转载地址:http://ohis.baihongyu.com/

你可能感兴趣的文章