2017-9-13(RxLifecycle)

作者: 721d739b6619 | 来源:发表于2017-09-14 12:22 被阅读140次

    RxLifecycle github地址

    官方定义

    This library allows one to automatically complete sequences based on a second lifecycle stream.
    This capability is useful in Android, where incomplete subscriptions can cause memory leaks.

    大概意思:在第二个生命周期基础上允许自动完成一系列操作。这个能力对于在安卓上并未完成订阅操作引起的内存泄漏很有用。(简而言之就是还没有来得及操作完一整套数据流时,出现生命周期的变化,而通过RxLifecycle得以处理从而避免内存泄漏)

    说了这么多其实它是解决什么问题的呢?

    其实就是当在网络请求中,假如网络慢,慢到我把当前页面关了,它才返回结果过来,请求是异步的,当异步请求结果返回后,我们会根据返回结果到ui线程中更新ui操作, 而当请求结果还没有返回,我们就将页面关闭了,于是就会出现访问ui操作空指针。

    看看几个重要的类

    • ActivityLifecycleProvider
    • BehaviorSubject

    ActivityLifecycleProvider是一个接口,共三个方法需实现

     /**
         * @return a sequence of {@link android.app.Activity} lifecycle events
         */
        @NonNull
        @CheckResult
        Observable<ActivityEvent> lifecycle();
    
        /**
         * Binds a source until a specific {@link ActivityEvent} occurs.
         * <p>
         * Intended for use with {@link Observable#compose(Observable.Transformer)}
         *
         * @param event the {@link ActivityEvent} that triggers unsubscription
         * @return a reusable {@link rx.Observable.Transformer} which unsubscribes when the event triggers.
         */
        @NonNull
        @CheckResult
        <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event);
    
        /**
         * Binds a source until the next reasonable {@link ActivityEvent} occurs.
         * <p>
         * Intended for use with {@link Observable#compose(Observable.Transformer)}
         *
         * @return a reusable {@link rx.Observable.Transformer} which unsubscribes at the correct time.
         */
        @NonNull
        @CheckResult
        <T> LifecycleTransformer<T> bindToLifecycle();
    

    ActivityLifecycleProvider 是一个公共实现接口,如果你的Activity不继承RxActivity,那么就需要实现该接口。

    Useful if you are writing utilities on top of rxlifecycle-components,
    or you are implementing your own component not supported in this library.

    看看如何实现

    private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
    
        @Override
        @NonNull
        @CheckResult
        public final Observable<ActivityEvent> lifecycle() {
            return lifecycleSubject.asObservable();
        }
    
        @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 RxLifecycle.bindActivity(lifecycleSubject);
        }
    

    public final Observable<ActivityEvent> lifecycle() {
    return lifecycleSubject.asObservable();
    }

    就是返回一个Observable,而这个Observable是没有被任何操作过的。
    asObservable();就是隐藏属性,避免其他人操作此Observable。

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

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

    其实第二第三个方法是类似的,稍有不同的是一个是手动指定绑定一个是自动到下一个ActivityEvent绑定。

    在ActivityLifecycleProvider接口对这两个方法描述:

    Binds a source until a specific {@link ActivityEvent} occurs.
    Binds a source until the next reasonable {@link ActivityEvent} occurs.

    大概意思:绑定一个source直到一个特定的(像ActivityEvent)发生
    绑定一个source直到下一个reasonabble(像ActivityEvent)发生
    这里的source其实就是指我们的数据流。

    这里着重看ActivityLifecycleProvider接口对bindUntilEvent的描述:

    Paste_Image.png

    源码叫我们通过compose使用此方法。参数event像ActivityEvent,当触发这个event时就会取消订阅。这里返回的是一个LifecycleTransformer。

    这里需要看看两个东西:

    • compose用法
    • Transformer是什么玩意(LifecycleTransformer本质就是Transformer)

    compose类似于flatMap(),但又区别于flatMap,主要compose是针对整个数据流。

    Transformer 就是一个转换器。

    看看RxLifecycle.bindUntilEvent(lifecycleSubject, event);在里面干了什么:

    lifecycleSubject即BehaviorSubject<ActivityEvent>发送消息和处理消息的。

    Paste_Image.png

    new UntilEventObservableTransformer<>(lifecycle, event);看看干了什么;

    Paste_Image.png Paste_Image.png

    到这里其实搞清楚source.takeUntil()和takeFirst()这两个操作符是干什么的,就真相大白了。

    • takeFirst()就是获取符合的前一个或多个
    • takeUntil()就是当出现某种情况时就终止

    现在来看其实就是当生命周期出现时,例如onStop发生时,而绑定的ActivityEvent也是STOP,那么就会停止对数据流的操作。

    BehaviorSubject既是Observer发送消息;又是Observable处理消息

    Paste_Image.png 图二

    图二的红色框框已经说明一切。

    BehaviorSubject需要在各个生命周期处发送消息


    Paste_Image.png Paste_Image.png

    目的其实也显而易见,就是监听生命周期的变化。因为前面已经说到当出现生命周期变化时,通过RxLifecycle得以处理避免内存泄漏

    那么如何通过RxLifecycle来处理呢?

     /**
         * @param observer 观察者
         * @param mObservable 用于发送消息
         * */
    public Observable subscribe(Observable mObservable, Observer observer) {
            /**
             * subscribeOn  做事情所在的线程
             * Schedulers 调度器 与 subscribeOn配套使用
             * */
            mObservable.subscribeOn(Schedulers.io())
                    //observeOn 指回调时候所在的线程
                    .observeOn(AndroidSchedulers.mainThread())                            
    .compose(getActivityLifecycleProvider().bindUntilEvent(ActivityEvent.DESTROY))  
                //意思是在Destroy生命周期取消订阅
                    //subscribe 订阅 observer 观察者
                    .subscribe(observer);
            return mObservable;
    

    这里我的注解都写得很清楚了,简而言之就是之前在各个生命周期发送消息,而这里就是在某一生命周期出现的情况下取消订阅消息。

    当然还有另一种写法:bindToLifecycle

    bindToLifecycle就是在onStart方法中绑定,在onStop方法被调用后就会解除绑定,以此类推。
    有一种特殊情况,如果在onPause/onStop方法中绑定,那么就会在它的下一个生命周期方法(onStop/onDestory)被调用后解除绑定。
    这里参考
    容华谢后的Android 使用RxLifecycle解决RxJava内存泄漏

    最后基于贴出代码

    BaseActivity

    public class BaseActivity extends AppCompatActivity implements ActivityLifecycleProvider, IBaseView {
        /**
         * BehaviorSubject 继承 Subject ,Subject是为主题
         * RxJava中常见的Subject有4种,
         * 分别是 AsyncSubject、 BehaviorSubject、 PublishSubject、 ReplaySubject
         * 一定要用Subcect.create()的方式创建并使用,
         * 不要用just(T)、from(T)、create(T)创建,否则会导致失效
         * Subject没法指定异步线程,更像是EventBus通过订阅来实现事件通知
         */
        private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           
    
            lifecycleSubject.onNext(ActivityEvent.CREATE);
        }
    
    
    
        @Override
        @NonNull
        @CheckResult
        public final Observable<ActivityEvent> lifecycle() {
            return lifecycleSubject.asObservable();
        }
    
        @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 RxLifecycle.bindActivity(lifecycleSubject);
        }
    
    
    
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
        }
    
        @Override
        @CallSuper
        protected void onStart() {
            super.onStart();
            lifecycleSubject.onNext(ActivityEvent.START);
        }
    
    
        @Override
        @CallSuper
        protected void onResume() {
            super.onResume();
            lifecycleSubject.onNext(ActivityEvent.RESUME);
        }
    
        @Override
        @CallSuper
        protected void onPause() {
            lifecycleSubject.onNext(ActivityEvent.PAUSE);
            super.onPause();
        }
    
        @Override
        @CallSuper
        protected void onStop() {
            lifecycleSubject.onNext(ActivityEvent.STOP);
            super.onStop();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //这就是lifecycleSubject发射数据
            lifecycleSubject.onNext(ActivityEvent.DESTROY);
           
        }
    
       
    }
    

    BaseMode

    public class BaseModel {
        protected Context mContext;
    
        public BaseModel(Context context) {
            mContext = context;
        }
    
        protected ActivityLifecycleProvider getActivityLifecycleProvider() {
            ActivityLifecycleProvider provider = null;
            if (null != mContext && mContext instanceof ActivityLifecycleProvider) {
                provider = (ActivityLifecycleProvider) mContext;
            }
            return provider;
        }
    
        /**
         * @param observer 观察者
         * @param mObservable 用于发送消息
         * */
        public Observable subscribe(Observable mObservable, Observer observer) {
            /**
             * subscribeOn  做事情所在的线程
             * Schedulers 调度器 与 subscribeOn配套使用
             * */
            mObservable.subscribeOn(Schedulers.io())
                    //observeOn 指回调时候所在的线程
                    .observeOn(AndroidSchedulers.mainThread())
                    //意思是在Destroy周期的时候取消请求(bindUntilEvent 没有发现Destroy周期时就不会停掉请求)
                    //这里也可以使用  .compose(getActivityLifecycleProvider().bindUntilEvent(ActivityEvent.STOP))指当Activity STOP时停止网络请求
                    .compose(getActivityLifecycleProvider().bindUntilEvent(ActivityEvent.DESTROY))
                    //.bindUntilEvent(ActivityEvent.DESTROY) 意思是在Destroy生命周期取消订阅
                    //subscribe 订阅 observer 观察者
                    .subscribe(observer);
            return mObservable;
        }
    
    }
    

    相关文章

      网友评论

        本文标题:2017-9-13(RxLifecycle)

        本文链接:https://www.haomeiwen.com/subject/hsblsxtx.html