RxLifecycle3介绍
使用RxLifecycle3目的:解决RxJava2使用中的内存泄漏问题。
RxLifecycl3e核心思想:通过监听Activity、Fragment的生命周期,来自动断开订阅防止内存泄漏。
例如,当使用RxJava订阅并执行耗时任务后,当Activity被finish时,如果耗时任务还未完成,没有及时取消订阅,就会导致Activity无法被回收,从而引发内存泄漏。
为了解决这个问题,就产生了RxLifecycle3,让RxJava2变得有生命周期感知,使得其能及时取消订阅,避免出现内存泄漏问题。
它可以让Observable发布的事件和当前的组件绑定,实现生命周期同步。 从而实现当前组件生命周期结束时,自动取消对Observable订阅。
目前对RxJava的内存泄漏有两种方案 (1)手动绑定生命周期,当前组件生命周期结束时,自动取消对Observable订阅;
(2)手动为RxJava2的每一次订阅进行控制,指定在哪个生命周期方法调用时取消订阅;
上述两种方式我都使用过,RxLifecycle3显然对于第一种方式,更简单直接,并且能够在Activity/Fragment容器的指定生命周期取消订阅,实在是好用。
以下代码在项目里,项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2
1.添加RxJava2和RxLifecycle3依赖(如果同步失败,可能是因为公司的网络有好多情况下连不到Goole的仓库,所以就要连接自己的手机热点进行同步,手机热点一般会同步成功的,但是注意流量消耗)。
//rxjava2框架導入
api 'io.reactivex.rxjava2:rxjava:2.2.10'
api 'io.reactivex.rxjava2:rxandroid:2.1.1'
//1.解决rxjava导致的内存泄漏的框架導入
api 'com.trello.rxlifecycle3:rxlifecycle:3.1.0'
// If you want to bind to Android-specific lifecycles
api 'com.trello.rxlifecycle3:rxlifecycle-android:3.1.0'
// If you want pre-written Activities and Fragments you can subclass as providers
api 'com.trello.rxlifecycle3:rxlifecycle-components:3.1.0'
// If you want pre-written support preference Fragments you can subclass as providers
api 'com.trello.rxlifecycle3:rxlifecycle-components-preference:3.1.0'
// If you want to use Android Lifecycle for providers
api 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle:3.1.0'
// If you want to use Kotlin syntax
api 'com.trello.rxlifecycle3:rxlifecycle-kotlin:3.1.0'
// If you want to use Kotlin syntax with Android Lifecycle
api 'com.trello.rxlifecycle3:rxlifecycle-android-lifecycle-kotlin:3.1.0'
// If you want to use Navi for providers
// DEPRECATED: Use rxlifecycle-android-lifecycle instead. This will be removed in a future release.
api 'com.trello.rxlifecycle3:rxlifecycle-navi:3.1.0'
2.Activity/Fragment需继承RxAppCompatActivity/RxFragment。
public abstract class BaseMvpRxAppActivity<V, T extends BasePresenter<V>> extends RxAppCompatActivity {
public class RegisterActivity extends BaseMvpRxAppActivity<IBaseView, LoginPresenterImpl>
implements IRegisterView {
3.?使用compose操作符绑定容器生命周期。
有两种方式:
方式1:使用bindToLifecycle()
以Activity为例,在Activity中使用bindToLifecycle()方法,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅,代码如下:
在onResume()进行绑定订阅,则在onPause()进行解除订阅,生命周期是两两对应的。
/**
* 无返回值,接口回调返回字符串
*
* @param rxAppCompatActivity
* @param observable
* @param onCommonSingleParamCallback
* @return
*/
public void responseStringRxAppActivityBindToLifecycle(RxAppCompatActivity rxAppCompatActivity, Observable<ResponseBody> observable, OnCommonSingleParamCallback<String> onCommonSingleParamCallback) {
observable.onTerminateDetach()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//解决rxjava导致的内存泄漏问题
.compose(rxAppCompatActivity.<ResponseBody>bindToLifecycle())
.subscribe(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws
Exception {
String responseString = responseBody.string();
LogManager.i(TAG, "responseString*****" + responseString);
onCommonSingleParamCallback.onSuccess(responseString);
// if (!isEmpty(responseString)) {
// BaseResponse baseResponse;
// try {
// baseResponse = JSON.parseObject(responseString, BaseResponse.class);
// } catch (Exception e) {
// //如果不是标准json字符串,就返回错误提示
// onCommonSingleParamCallback.onError(BaseApplication.getInstance().getResources().getString(R.string.server_sneak_off));
// return;
// }
// onCommonSingleParamCallback.onSuccess(responseString);
// } else {
// onCommonSingleParamCallback.onError(BaseApplication.getInstance().getResources().getString(R.string.server_sneak_off));
// }
// ReadAndWriteManager manager = ReadAndWriteManager.getInstance();
// manager.writeExternal("mineLog.txt",
// responseString,
// new OnCommonSingleParamCallback<Boolean>() {
// @Override
// public void onSuccess(Boolean success) {
// LogManager.i(TAG, "success*****" + success);
// manager.unSubscribe();
// }
//
// @Override
// public void onError(String error) {
// LogManager.i(TAG, "error*****" + error);
// manager.unSubscribe();
// }
// });
}
}
, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
LogManager.i(TAG, "throwable*****" + throwable.toString());
LogManager.i(TAG, "throwable message*****" + throwable.getMessage());
// 异常处理
onCommonSingleParamCallback.onError(BaseApplication.getInstance().getResources().getString(R.string.request_was_aborted));
}
}
);
}
方式2:使用bindUntilEvent()
使用ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。使用bindUntilEvent指定在哪个生命周期方法调用时取消订阅:
/**
* 无返回值,接口回调返回字符串
*
* @param rxAppCompatActivity
* @param observable
* @param onCommonSingleParamCallback
* @return
*/
public void responseStringRxAppActivityBindUntilEvent(RxAppCompatActivity rxAppCompatActivity, Observable<ResponseBody> observable, OnCommonSingleParamCallback<String> onCommonSingleParamCallback) {
observable.onTerminateDetach()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//解决rxjava导致的内存泄漏问题
.compose(rxAppCompatActivity.<ResponseBody>bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws
Exception {
String responseString = responseBody.string();
LogManager.i(TAG, "responseString*****" + responseString);
onCommonSingleParamCallback.onSuccess(responseString);
// if (!isEmpty(responseString)) {
// BaseResponse baseResponse;
// try {
// baseResponse = JSON.parseObject(responseString, BaseResponse.class);
// } catch (Exception e) {
// //如果不是标准json字符串,就返回错误提示
// onCommonSingleParamCallback.onError(BaseApplication.getInstance().getResources().getString(R.string.server_sneak_off));
// return;
// }
// onCommonSingleParamCallback.onSuccess(responseString);
// } else {
// onCommonSingleParamCallback.onError(BaseApplication.getInstance().getResources().getString(R.string.server_sneak_off));
// }
// ReadAndWriteManager manager = ReadAndWriteManager.getInstance();
// manager.writeExternal("mineLog.txt",
// responseString,
// new OnCommonSingleParamCallback<Boolean>() {
// @Override
// public void onSuccess(Boolean success) {
// LogManager.i(TAG, "success*****" + success);
// manager.unSubscribe();
// }
//
// @Override
// public void onError(String error) {
// LogManager.i(TAG, "error*****" + error);
// manager.unSubscribe();
// }
// });
}
}
, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
LogManager.i(TAG, "throwable*****" + throwable.toString());
LogManager.i(TAG, "throwable message*****" + throwable.getMessage());
// 异常处理
onCommonSingleParamCallback.onError(BaseApplication.getInstance().getResources().getString(R.string.request_was_aborted));
}
}
);
}
Fragment也有同样的两种方式,只是方法名会有所不同。
这两种方式都可以使用,都是为了解决RxJava使用中的内存泄漏问题。
推荐Android开源项目
项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。
项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2
|