rxjava : RxLifeCycle解析

参考:

Android技能树 — Rxjava取消订阅小结(2):RxLifeCycle

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.<Long>bindUntilEvent(ActivityEvent.PAUSE))
                .subscribe(new Consumer<Long>() {
                    @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.<Long>bindToLifecycle())
                .subscribe(new Consumer<Long>() {
                    @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.<Long>` 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.<Long>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Consumer<Long>() {
                    @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<ActivityEvent> {
    //创建一个BehaviorSubject,用来做takeUntil中的第二个Observable,
    //让其在核实的生命周期发送信息。
    private final BehaviorSubject<ActivityEvent> lifecycleSubject = 
    							BehaviorSubject.create();

    public RxAppCompatActivity() {
    }

    @ContentView
    public RxAppCompatActivity(@LayoutRes int contentLayoutId) {
        super(contentLayoutId);
    }

    @NonNull
    @CheckResult
    public final Observable<ActivityEvent> lifecycle() {
        return this.lifecycleSubject.hide();
        //使用hide()方法把这个subject暴露出去
    }

    @NonNull
    @CheckResult
    public final <T> LifecycleTransformer<T> bindUntilEvent(
    									@NonNull ActivityEvent event) {
    	//手动解除订阅
        return RxLifecycle.bindUntilEvent(this.lifecycleSubject, event);
    }

    @NonNull
    @CheckResult
    public final <T> LifecycleTransformer<T> 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 <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);
        }
    });
}


//将给定的源绑定到生命周期。 
//此帮助程序会自动(根据生命周期序列本身)确定源应该何时停止发射物品。
//请注意,对于此方法,它假定给定生命周期发出的any事件表示生命周期已结束。
public static <T, R> LifecycleTransformer<T> bind(
					@Nonnull final Observable<R> lifecycle) {
    return new LifecycleTransformer<>(lifecycle);
}

LifecycleTransformer 实现的apply方法:

//observable : 生命周期
LifecycleTransformer(Observable<?> observable) {
    checkNotNull(observable, "observable == null");
    this.observable = observable;
}

//upstream : 我们自己的observable
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
	//当observable发射数据,upstream就会停止
    return upstream.takeUntil(observable);
}

总结:

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

自动解除订阅:

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

这里 bindToLifecycle() 实质调用:

RxLifecycleAndroid.bindActivity(this.lifecycleSubject);

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


private static final Function<ActivityEvent, ActivityEvent> 
			ACTIVITY_LIFECYCLE = new Function<ActivityEvent, ActivityEvent>() {
    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 <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));
}

这里 bind() 实质调用:

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

private static <R> Observable<Boolean> takeUntilCorrespondingEvent(
								final Observable<R> lifecycle,
								final Function<R, R> correspondingEvents) {
    return Observable.combineLatest(
    	//第一个Observable:记录在哪个生命周期去取消订阅。
        lifecycle.take(1).map(correspondingEvents),
        //第二个Observable:在不同生命周期发送不同事件,
        //当二个事件和第一个事件相同时候就说明要取消订阅了。
        //但是我们第一次要跳过,因为第一个事件是在订阅时候发生的 。
        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方法和手动解除订阅是一样的:
public static <T, R> LifecycleTransformer<T> bind(
					@Nonnull final Observable<R> 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就会取消订阅了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值