Rx系列Android开发经验谈程序员

2017-9-13(RxLifecycle)

2017-09-14  本文已影响140人  721d739b6619

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是一个接口,共三个方法需实现

 /**
     * @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类似于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()这两个操作符是干什么的,就真相大白了。

现在来看其实就是当生命周期出现时,例如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;
    }

}
上一篇下一篇

猜你喜欢

热点阅读