RxLifecycle使用和源码分析

RxJava内存泄漏

  • 为什么RxJava会发生内存泄漏?

    ​ 在当前页面用RxJava发布订阅后,如果当期页面finish时,没有及时取消订阅,这会导致Activity或Fragment无法回收,从而发生内存泄漏。

  • RxLifecycle可以通过绑定生命周期的方式,来解决RxJava内存泄漏的问题。

使用

  • 首先需要依赖以下两个库,从而实现两种不同的方法

    // 依赖以下两个库,会自动引用基础库与Android库
    compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
    compile 'com.trello.rxlifecycle2:rxlifecycle-navi:2.1.0'
    
  • 方法一:继承RxAppCompatActivity

    public class RxLifecycleActivity extends RxAppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_rxlifecycle_components);
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            Observable.interval(1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                //使用compose(this.bindToLifecycle())方法绑定Activity的生命周期
                //可以替换成.compose(this.<Long>bindUntilEvent(ActivityEvent.STOP))
                    .compose(this.<Long>bindToLifecycle())
                    .subscribe(...);
        }
    }
    
    • 在onStart方法中调用compose进行绑定,则在onStop方法被调用时自动取消绑定,以此类推。
    • 使用bindUntilEvent方法参数要注意遵守上一条的规则。
    • compose方法要在subscribeOn方法之后调用,否则如果在被观察者中执行了阻塞方法,比如Thread.sleep(),取消订阅后该阻塞方法不会被中断。
  • 方法二:继承NaviActivity

    public class RxLifecycleNaviActivity extends NaviActivity {
        //通过LifecycleProvider对象调用bindToLifecycle或者bindUntilEvent方法
    	private final LifecycleProvider<ActivityEvent> provider
                = NaviLifecycle.createActivityLifecycleProvider(this);
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_rxlifecycle_navi);
            initData();
        }
    
        private void initData() {
            Observable.interval(1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                //绑定Activity的生命周期
                //可替换成.compose(provider.<Long>bindToLifecycle())
                    .compose(provider.<Long>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(...);
        }
    }
    
    • 使用的是MVP架构,可把LifecycleProvider对象直接传给Presenter层使用。

原理解析

  • RxAppCompatActivity:

    public abstract class RxAppCompatActivity extends AppCompatActivity implements LifecycleProvider<ActivityEvent> {
    
        //通过Subject来监听Activity生命周期事件并对外发射
        private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
    
        @Override
        @NonNull
        @CheckResult
        public final Observable<ActivityEvent> lifecycle() {
            return lifecycleSubject.hide();
        }
    
        //返回LifecycleTransformer对象
        @Override
        @NonNull
        @CheckResult
        public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
            return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
        }
    
        //返回LifecycleTransformer对象
        @Override
        @NonNull
        @CheckResult
        public final <T> LifecycleTransformer<T> bindToLifecycle() {
            return RxLifecycleAndroid.bindActivity(lifecycleSubject);
        }
    
        //在Activity不同的生命周期,BehaviorSubject对象会发射对应的ActivityEvent
        @Override
        @CallSuper
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            lifecycleSubject.onNext(ActivityEvent.CREATE);
        }
    
        @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
        @CallSuper
        protected void onDestroy() {
            lifecycleSubject.onNext(ActivityEvent.DESTROY);
            super.onDestroy();
        }
    }
    
    • 可以看到核心两个方法bindToLifecycle和bindUntilEvent都是返回一个LifecycleTransformer对象,那再去了解下LifecycleTransformer。
  • LifecycleTransformer:

    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);
        }
        //隐藏其余代码,这里只以Observable为例
        ...
    }
    
    • LifecycleTransformer是实现了(Observable、Flowable等)的Transformer接口。
    • 以Observable为例,实际上就是通过传入一个Observable序列并存储为成员,然后作为参数给上游的数据源执行takeUntil方法。
    • takeUntil操作符: TakeUntil使用一个标志Observable作为参数来判断是否发射数据,当标志Observable没有发射数据时,调用takeUntil操作符的Observable正常发射数据,而一旦标志Observable发射过了数据则后面的数据都会被丢弃。
    • 既然通过bindToLifecycle和bindUntilEvent方法返回一个LifecycleTransformer对象,那我们看看compose或得到LifecycleTransformer对象做了什么。
  • compose:

    public final <R> Observable<R> compose(ObservableTransformer<? super T, ? extends R> composer) {
         return wrap(((ObservableTransformer<T, R>) ObjectHelper.requireNonNull(composer, "composer 	is null")).apply(this));
    }
    
    //wrap只是把ObservableSource转换成Observable
    public static <T> Observable<T> wrap(ObservableSource<T> source) {
         ObjectHelper.requireNonNull(source, "source is null");
         if (source instanceof Observable) {
            return RxJavaPlugins.onAssembly((Observable<T>)source);
         }
         return RxJavaPlugins.onAssembly(new ObservableFromUnsafeSource<T>(source));
    }
    
    • compose最终执行的是ObservableTransformer的apply方法并把原始Observable通过参数传进去了,执行LifecycleTransformer的apply方法了,实际上就是执行了upstream.takeUntil(observable)。upstream就是原始的Observable,而observable其实就是Activity里面维护的那个BehaviorSubject。
  • bindActivity:

    public final <T> LifecycleTransformer<T> bindToLifecycle() {
        //通过bindActivity方法,返回了LifecycleTransformer
        return RxLifecycleAndroid.bindActivity(lifecycleSubject);
    }
    
    • 我们看看bindActivity是怎么返回LifecycleTransformer对象的。
    public static <T> LifecycleTransformer<T> bindActivity(@NonNull final Observable<ActivityEvent> lifecycle) {
        //里面只是简单的调用了bind方法
        return bind(lifecycle, ACTIVITY_LIFECYCLE);
    }
    
    //了解下bind方法
    public static <T, R> LifecycleTransformer<T> bind(@Nonnull Observable<R> lifecycle,
    @Nonnull final Function<R, R>correspondingEvents) {
        //通过takeUntilCorrespondingEvent方法返回一个Observable给bind方法
        return bind(takeUntilCorrespondingEvent(lifecycle.share(), correspondingEvents));
    }
    
    //了解下takeUntilCorrespondingEvent方法
    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);
    }
    
    • combineLatest 操作符用来将多个Observable发射的数据组装起来然后在发射。

    • lifecycle.take(1)指的是获取发射事件的前一个,如果是take(3)就是获取前三个事件。比如在onCreate()中执行了bindToLifecycle,那么lifecycle.take(1)指的就是ActivityEvent.CREATE。

    • 而map(correspondingEvents)中的参数就是ACTIVITY_LIFECYCLE

      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");
                }
              }
           };
      
      • 这个方法就是通过调用的bindToLifecycle的生命周期而获取到的事件,来获得到要取消绑定的生命周期事件。比如onCreate()中执行了bindToLifecycle,那么ActivityEvent.CREATE能获取到ActivityEvent.DESTROY,就是要在onDestry方法中取消订阅。
    • 第二个参数lifecycle.skip(1)就是除去第一个事件保留剩下的事件。以ActivityEvent.Create为例,这里就剩下:

      ActivityEvent.START
      ActivityEvent.RESUME
      ActivityEvent.PAUSE
      ActivityEvent.STOP
      ActivityEvent.DESTROY

    • 第三个参数就是拿第一个参数获取到的事件和第二个参数获取到的事件集合进行比对从而获取到新的序列,比如通过上面的就能得到:

      false,false,fasle,false,true

      当Activity运行到为false的生命周期时是不会取消订阅的,当运行到true的生命周期就取消订阅。

    • onErrorReturn是对异常的处理

    • filter是对要发送的事件进行筛选,这里只有当运行到需要取消订阅的生命周期才会发送事件,因为发送了事件就就导致之前介绍的takeUntil操作符发挥作用,从而实现取消订阅。

原理总结

  • 原始的Observable通过takeUntil和BehaviorSubject绑定,当BehaviorSubject发出数据即Activity的生命周期走到和指定销毁的事件一样时,原始的Observable就终止发射数据了。

参考

  • 感谢以下文章作者的努力:

解决RxJava内存泄漏(前篇):RxLifecycle详解及原理分析

rxlifecycle2原理分析

Android 使用RxLifecycle解决RxJava内存泄漏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值