一、为什么要做生命周期管理?
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()) 方法了,和第一种方式相比,更加灵活。
原文链接:https://blog.youkuaiyun.com/fitaotao/article/details/117522260