Android RxJava生命周期管理解决方案整理

一、为什么要做生命周期管理?

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
        //TODO
    }
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
    @Override
    public void accept(String str) throws Exception {
        
    }
});

这样就是一个简单的异步处理,但是如果只是这样使用肯定是不行,因为在 Android 开发过程中,如果在进行耗时操作的时候,操作还没有结束,这个时候退出的当前 Activity,这个时候,这段代码的处理并不会因为 Activity 的退出而结束,就会导致内存泄漏等问题,严重的时候甚至会导致 APP 闪退。

 

二、如何管理生命周期?

1、使用CompositeDisposable 这个类,手动实现对 RxJava 的管理

原理:每次使用 RxJava,都将其生成的 Disposable 对象添加到 CompositeDisposable 对象中,并在每个界面结束(onDestroy)的时候,调用 CompositeDisposable 对象的 clear()方法取消事件。

实现过程:1.实现一个统一管理的基准类

public class CommonComposite {

    private CompositeDisposable mCompositeDisposable;

    public void addDisposable(Disposable disposable) {
        if (mCompositeDisposable == null || mCompositeDisposable.isDisposed()) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }

    public void unDisposable() {
        if (mCompositeDisposable != null) {
            mCompositeDisposable.dispose();
        }
    }
}

2.在每次使用RxJava时,在最后的订阅subscribe之前,统一添加doOnSubscribe()方法,并在里面调用上面的addDisposable(),如下:

RetrofitClient.get()
        .invoke(CommandId.CASH_OUT_APPLY_LIST, params.toString())
        .doOnSubscribe(new Consumer<Disposable>() {
            @Override
            public void accept(Disposable disposable) throws Exception {
                addDisposable(disposable);
            }
        })
        .subscribe(new CommonObserver<CashOutApplyList>() {
            @Override
            public void onSuccess(CashOutApplyList data) {
                mView.updateCashOutApplyList(data.getRows());
            }

            @Override
            public void onError(String msg, String code) {
                mView.updateCashOutApplyList(msg);
            }
        });

3.在页面销毁的回调方法中(如onDestroy)中调用unDisposable()进行取消事件订阅

@Override
protected void onDestroy() {
    if( mPresenter!=null){
        mPresenter.unsubscribe();
    }
    super.onDestroy();
}
@Override
public void unsubscribe() {
    unDisposable();
}

2、使用RxLifecycle

Github:https://github.com/trello/RxLifecycle

实现过程:1.添加依赖

implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'

2.继承容器类

Activity/Fragment 需要继承 RxAppCompatActivity/RxFragment,主要支持如下几种容器类:

 

 

只需要在项目中针对base类的容器中继承实现对应的Rx类即可,这一步主要是对生命周期的回调事件进行监听。

3.绑定容器生命周期

以Activity为例,主要有如下两种方法(Fragment也有同样的两种方法,只是方法名会有所不同):

bindUntilEvent(@NonNull ActivityEvent event) 

bindToLifecycle()

(1)bindUntilEvent(@NonNull ActivityEvent event)

//该方法指定在哪个生命周期方法调用时取消订阅

其中ActivityEvent是一个枚举类,对应于Activity的生命周期

public enum ActivityEvent {
    CREATE,
    START,
    RESUME,
    PAUSE,
    STOP,
    DESTROY
}

使用如下:指定在生命周期onDestory()时,取消订阅

@SuppressLint("AutoDispose")
    private void test() {
      Observable.interval(1, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                        Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                        Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                    }
                })
                .compose(bindUntilEvent(ActivityEvent.DESTROY))//指定在生命周期onDestory()时,取消订阅
                .subscribe(new Observer<Long>() {

                    Disposable disposable;

                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG, "=======" + "onSubscribe:" + "=========");
                        disposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        Log.e(TAG, "=======" + "onNext:" + aLong + "=========");
                        Log.e(TAG, "=======" + "onNext,Thread:" + Thread.currentThread().getName() + "=========");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "=======" + "onError:" + "=========");
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "=======" + "onComplete:" + "=========");
                    }
                });
    }

运行结果如下:

(2)使用bindToLifecycle()

//在某个生命周期进行绑定,在对应的生命周期进行订阅解除。具体的对应关系如下:

使用如下:在生命周期onStart()时进行绑定(就是test2()方法放在onStart()中),在onStop()时取消

@SuppressLint("AutoDispose")
    private void test2() {
        Observable.interval(1, TimeUnit.SECONDS)
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                        Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                        Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                    }
                })
                .compose(bindToLifecycle())//在某个生命周期进行绑定,在对应的生命周期进行订阅解除。如在onResume()里调用test2()进行绑定订阅,则在onPause()进行解除订阅,生命周期是两两对应的。
                .subscribe(new Observer<Long>() {

                    Disposable disposable;

                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG, "=======" + "onSubscribe:" + "=========");
                        disposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) {
                        Log.e(TAG, "=======" + "onNext:" + aLong + "=========");
                        Log.e(TAG, "=======" + "onNext,Thread:" + Thread.currentThread().getName() + "========="); 
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "=======" + "onError:" + "=========");
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "=======" + "onComplete:" + "=========");
                    }
                });

运行结果如下:

原理分析:

主要就是:compose、BehaviorSubject、LifecycleTransformer、takeUntil、take、skip、combineLatest这几部分;详细参考 RxLifecycle的使用及原理分析

它的设计思路:

1.在Activity中,定义一个Observable(Subject),在不同的生命周期发射不同的事件;

2.通过compose操作符(内部实际上还是依赖takeUntil操作符),定义了上游数据,当其接收到Subject的特定事件时,取消订阅;

3.Subject的特定事件并非是ActivityEvent,而是简单的boolean,它已经内部通过combineLast操作符进行了对应的转化。

实际上,Subject和ActivityEvent对RxLifecycle的使用者来讲,是对应隐藏的。我们只需要调用它提供给我们的API,而内部的实现者我们无需考虑,但是也只有去阅读和理解了它的思想,我们才能更好的选择使用这个库

 

3、使用RxAutoDispose(分引入LifeCycle和不引入)

Github:https://github.com/uber/AutoDispose

实现过程:1.添加依赖

implementation 'com.uber.autodispose:autodispose:1.3.0'
implementation 'com.uber.autodispose:autodispose-android-archcomponents:1.3.0'

2.在代码中使用(两种使用方式)

//在Activity或Fragment中使用
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))//方式一,自动绑定,在哪里注册,那么就在它的对立时期解除绑定
.as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))//方式二:指定解除绑定周期
private void test() {
    Observable.interval(0, 1, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnDispose(new Action() {
                @Override
                public void run() throws Exception {
                    //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                    Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                    Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                }
            })
            //AutoDispose在被订阅时,获取到Activity当前的生命周期,并找到对应需要结束订阅的生命周期事件
            .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))//方式一,自动绑定,在哪里注册,那么就在它的对立时期解除绑定
            .subscribe(new Observer<Long>() {

                Disposable disposable;

                @Override
                public void onSubscribe(Disposable d) {
                    Log.e(TAG, "=======" + "onSubscribe:" + "=========");
                    disposable = d;
                }

                @Override
                public void onNext(Long aLong) {
                    Log.e(TAG, "=======" + "onNext:" + aLong + "=========");
                    Log.e(TAG, "=======" + "onNext,Thread:" + Thread.currentThread().getName() + "=========");
                    textview.setText(String.valueOf(aLong));
                    if (aLong >= 10) {
                        disposable.dispose();
                        Log.e(TAG, "=======" + "dispose" + "=========");//这里会落后于doOnDispose执行
                    }
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "=======" + "onError:" + "=========");
                }

                @Override
                public void onComplete() {
                    Log.e(TAG, "=======" + "onComplete:" + "=========");
                }
            });
}

原理分析:

as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this))

(1)参数this:

就是Activity本身,当然它也可以是Fragment,这个参数对象只有一个要求,就是必须实现LifecycleOwner接口。LifecycleOwner接口是Google Android官方架构组件:Lifecycle的一个重要组件,在androidx中,ComponentActivity实现了这个接口,实现了这个接口的对象都拥有生命周期(Lifecycle)。这意味着,只要是实现了LifecycleOwner的类,都可以作为参数传给AutoDispose,用以控制Observable和组件生命周期的绑定。

(2)如何实现生命周期的绑定

参考RxLifecycle的原理:

1.在Activity中,定义一个Observable(Subject),在不同的生命周期发射不同的事件; 2.通过compose操作符(内部实际上还是依赖takeUntil操作符),定义了上游数据,当其接收到Subject的特定事件时,取消订阅; 3.Subject的特定事件并非是ActivityEvent,而是简单的boolean,它已经内部通过combineLast操作符进行了对应的转化

AutoDispose获取了Activity(LifecycleOwner)对象,并定义了一个新的Observable,在Activity的不同生命周期中,发射对应的事件。

和RxLifecycle很类似的是,AutoDispose在被订阅时,获取到Activity当前的生命周期,并找到对应需要结束订阅的生命周期事件:

private static final CorrespondingEventsFunction<Lifecycle.Event> DEFAULT_CORRESPONDING_EVENTS =
    lastEvent -> {
      switch (lastEvent) {
        case ON_CREATE:
          return Lifecycle.Event.ON_DESTROY;
        case ON_START:
          return Lifecycle.Event.ON_STOP;
        case ON_RESUME:
          return Lifecycle.Event.ON_PAUSE;
        case ON_PAUSE:
          return Lifecycle.Event.ON_STOP;
        case ON_STOP:
        case ON_DESTROY:
        default:
          throw new LifecycleEndedException("Lifecycle has ended! Last event was " + lastEvent);
      }
    };

也就是说,在我们的ObservableA订阅时,就已经知道了自己在Activity的哪个生命周期让AutoDispose内部自定义的ObservableB自动发射事件,ObservableA监听到这个事件时且未dispose,解除订阅避免内存泄漏。

毕竟内存泄漏是少数,更大的可能是ObservableA早就执行完任务dispose了,因此ObservableB实际上就是一个Maybe,类似于

ObservableA.takeUntil( Maybe< true > )

核心代码:

public static <E> CompletableSource resolveScopeFromLifecycle(
    Observable<E> lifecycle, final E endEvent, @Nullable final Comparator<E> comparator) {
  Predicate<E> equalityPredicate;
  if (comparator != null) {
    equalityPredicate = e -> comparator.compare(e, endEvent) >= 0;
  } else {
    equalityPredicate = e -> e.equals(endEvent);
  }
  return lifecycle.skip(1).takeUntil(equalityPredicate).ignoreElements();
}

(3)as方法执行后生成了一个什么?

as方法内部生成了一个AutoDisposeConverter对象,类似于compose,不同的是,Observable通过compose生成的对象还是Observable,但as方法生成的则是一个新的对象:

public final <R> R as(@NonNull ObservableConverter<T, ? extends R> converter)

实际上,抛开复杂的细节,AutoDispose最终将原来的Observable,生成了一个新的AutoDisposeObservable对象, 在执行订阅时,也生成了一个新的AutoDisposingObserverImpl对象

(4)AutoDispose和RxLifecycle的区别

原理相似,但是RxLifecycle有如下局限性:

1、需要继承父类(RxActivity / RxFragment等)

2、如何处处绑定生命周期?

简单的例子,我的RecyclerView的Adapter中订阅了Observable,亦或者,在MVP的架构或者 MVVM架构中,我的presenter或者我的viewModel无法直接获取RxActivity的引用(作为View 层,更应该抽象为一个接口与Presenter进行交互)。 这意味着,想要进行Observable的生命周期绑定,在RecyclerView的Adapter中,我必须要通 过将Activity作为依赖,注入到Adapter中: new ListAdapter(RxActivity activity); 而对于Presenter,我需要对View抽象接口进行instanceof 的判断:

if (view instanceof RxActivity) {

return bindToLifecycle((RxActivity) view);

}

 

4、如何把AutoDispose添加到目前的Android项目中

 

(以MVP架构为例)

方式一:

(1)封装Util类

static class RxAutoDisposeUtils {

    private RxAutoDisposeUtils() {
    }

    public static <T> AutoDisposeConverter<T> bindLifecycle(LifecycleOwner lifecycleOwner) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner));
    }

    public static <T> AutoDisposeConverter<T> bindLifecycle(LifecycleOwner lifecycleOwner, Lifecycle.Event event) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, event));
    }

    public static <T> AutoDisposeConverter<T> bindDestroyLifecycle(LifecycleOwner lifecycleOwner) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner, Lifecycle.Event.ON_DESTROY));
    }
}

(2)在BaseActivity/BaseFragment中添加代码

只要持有LifecycleOwner对象,Observable都可以通过RxLifecycleUtils.bindLifecycle(LifecycleOwner)进行绑定

fun <T> bindLifecycle(): AutoDisposeConverter<T> {
        return AutoDispose.autoDisposable<T>(AndroidLifecycleScopeProvider.from(lifecycle))

//        return AutoDispose.autoDisposable<T>(
//            AndroidLifecycleScopeProvider.from(
//                lifecycleOwner,
//                Lifecycle.Event.ON_DESTROY
//            )
//        )
    }

(3)在任何BaseActivity的实现类中,我们都可以通过下述代码实现Observable的生命周期绑定

Observable.interval(0, 1, TimeUnit.SECONDS)
        .as(bindLifecycle())
        .subscribe()

(4)在Presenter中通过持有Activity的对象,达到Observable生命周期的绑定(类似RxLifecycle的使用)

public interface BaseView {
    <T> LifecycleTransformer<T> getActivityLifecycleProvider();
    LifecycleOwner getLifecycleOwner();
}
public class RxJavaContract {
    interface View extends BaseView {
        void onNetRequest();
    }
    interface Presenter extends BasePresenter {
        void netRequest();
    }
}
//在BaseActivity中实现如下方法
open fun <T> getActivityLifecycleProvider(): LifecycleTransformer<T> {
//        return bindToLifecycle() //可以绑定Activity生命周期
        return bindUntilEvent(ActivityEvent.DESTROY);//可以绑定Activity生命周期
    }

    fun getLifecycleOwner(): LifecycleOwner {
        return this
    }
public class RxJavaPresenter implements RxJavaContract.Presenter {
    private RxJavaContract.View mView;
    Observable.interval(1, TimeUnit.SECONDS)
            .compose(mView.getActivityLifecycleProvider())
            .subscribe()
}

方式二:使用Google官方Lifecycle组件

(1)首先让我们的IPresenter接口实现LifecycleObserver接口

//实现了 LifecycleObserver 接口的类可以和实现了 LifecycleOwner 接口的类无缝工作
//,因为 LifecycleOwner 可以提供一个 Lifecycle 对象,而 LifecycleObserver 就正
//需要对这个 Lifecycle 对象进行监听呢。 LifecycleOwner 是从特定的类(比如
// Activity 或者 Fragment 等)中抽象出来的Lifecycle 的持有者
interface IPresenter : LifecycleObserver {

    //使用Google官方Lifecycle组件
    // 使用注解  @OnLifecycleEvent 来表明该方法需要监听指定的生命周期事件
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(@NotNull owner: LifecycleOwner)

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy(@NotNull owner: LifecycleOwner)

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onLifecycleChanged(@NotNull owner: LifecycleOwner, @NotNull event: Lifecycle.Event)
}

(2)然后在BasePresenter中管理LifecycleOwner

abstract class BaseNewPresenter :
    IPresenter {

    private lateinit var lifecycleOwner: LifecycleOwner

    override fun onCreate(owner: LifecycleOwner) {
        Log.e("LifecycleOwner", "=======" + "onCreate:" + "=========")
        this.lifecycleOwner = owner
    }

    override fun onDestroy(owner: LifecycleOwner) {

    }

    override fun onLifecycleChanged(owner: LifecycleOwner, event: Lifecycle.Event) {

    }

    fun <T> bindLifecycle(): AutoDisposeConverter<T> {
        return AutoDispose.autoDisposable<T>(AndroidLifecycleScopeProvider.from(lifecycleOwner))

//        return AutoDispose.autoDisposable<T>(
//            AndroidLifecycleScopeProvider.from(
//                lifecycleOwner,
//                Lifecycle.Event.ON_DESTROY
//            )
//        )
    }
}

(3)最后在Activity中添加Presenter为观察者,观察Activity的生命周期

abstract class BaseNewMvpActivity<P : IPresenter> : BaseNewActivity(){
    lateinit var presenter: P

    override fun onCreate(savedInstanceState: Bundle?) {
        presenter = createPresenter()
        //这一行,如此每当Activity发生了对应的生命周期改变,Presenter就会执行
        //对应事件注解的方法
        lifecycle.addObserver(presenter)
        super.onCreate(savedInstanceState)
    }
}

(4)Presenter中的使用

public class RxAutoDisposePresenter extends BaseNewPresenter implements RxAutoDisposeContract.Presenter {

    private RxAutoDisposeContract.View mView;
    private Context mContext;
    private String TAG = RxAutoDisposePresenter.class.getSimpleName();

    public RxAutoDisposePresenter(Context context, RxAutoDisposeContract.View view) {
        this.mContext = context;
        this.mView = view;
    }

    @Override
    public void netRequest() {
        Observable.interval(0, 1, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnDispose(new Action() {
                    @Override
                    public void run() throws Exception {
                        //doOnDispose:当调用 Disposable 的 dispose() 之后回调该方法
                        Log.e(TAG, "=======" + "doOnDispose:" + "=========");
                        Log.e(TAG, "=======" + "doOnDispose,Thread:" + Thread.currentThread().getName() + "=========");
                    }
                })
                .as(bindLifecycle())//方式二:指定解除绑定周期
                .subscribe(new BaseObserver<Long>() {
                    @Override
                    public void onSuccess(Long data) {
                        Log.e(TAG, "=======" + "onSuccess:" + data + "=========");
                        mView.onNetRequest(data);
                    }

                    @Override
                    public void onError(String msg, String code) {
                        mView.onNetRequest(Long.parseLong(code));
                    }
                });
    }
}

我们即使在Presenter中,也能任意使用myObservable.as(bindLifecycle()) 方法了,和第一种方式相比,更加灵活。

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android 中,AMS(Activity Manager Service)负责管理 Activity 的生命周期。Activity 有四个状态:运行状态、暂停状态、停止状态和销毁状态。当一个 Activity 运行时,它可以被用户看到,并响应用户的交互;当它被暂停时,它被部分遮挡,但仍然在屏幕上存在;当它被停止时,它被完全遮挡,但其状态仍然保留在内存中;当它被销毁时,它被完全删除,其状态也从内存中释放。 Activity 生命周期管理的关键是回调方法。Android 系统提供了一组回调方法,使得开发者可以在 Activity 的不同状态下执行相应的操作。 以下是 Activity 生命周期的回调方法: 1. onCreate(): Activity 被创建时调用,通常用来完成界面的初始化和数据的加载。 2. onStart(): Activity 变为可见时调用,此时 Activity 进入运行状态。 3. onResume(): Activity 处于前台并处于运行状态时调用,此时 Activity 可以响应用户的交互。 4. onPause(): 当其他 Activity 显示在前台并且当前 Activity 处于可见状态时调用,此时 Activity 进入暂停状态。 5. onStop(): Activity 完全被遮挡时调用,此时 Activity 进入停止状态。 6. onRestart(): 当 Activity 从停止状态重新进入运行状态时调用。 7. onDestroy(): Activity 被销毁时调用,通常用来释放内存或资源。 开发者应根据自己的应用需求在这些回调方法中编写相应的业务逻辑,从而实现自己的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值