1.简单介绍RxLifecycle
1.1.使用原因。
在使用rxjava的时候,如果没有及时解除订阅,在退出activity的时候,异步线程还在执行。
对activity还存在引用,此时就会产生内存泄漏。
RxLifecycle就是为了解决rxjava导致的内存泄漏而产生的。
1.2.RxLifecycle可以做到什么呢?
它可以让Observable发布的事件和当前的组件绑定,实现生命周期同步。
从而实现当前组件生命周期结束时,自动取消对Observable订阅。
核心思想:通过监听Activity、Fragment的生命周期,来自动断开订阅防止内存泄漏。
1.3.参考文献。
Rxandroid的github地址:https://github.com/ReactiveX/RxAndroid
Rxlifecycle的github地址:https://github.com/trello/RxLifecycle
参考文章:在mvp中使用rxlifecycle避免rxjava的内存泄漏。
2.使用方法
2.1.添加最新的依赖
//rxjava的依赖 compile ‘io.reactivex.rxjava2:rxandroid:2.0.1‘ compile ‘io.reactivex.rxjava2:rxjava:2.1.7‘ //rxlifecycle的依赖 compile ‘com.trello.rxlifecycle2:rxlifecycle-android-lifecycle-kotlin:2.2.1‘
2.2.Activity以及Fragment的继承
Activity需要继承RxAppCompatActivity。==>比如这么一个类
public class BaseActivity extends RxAppCompatActivity
Fragment需要继承RxFragment。==>比如这么一个类
public abstract class BaseFragment<T extends IBasePresenter> extends RxFragment implements IBaseView<T>
2.3.绑定生命周期。
自己写一个接口,里面定义一个bindToLife()函数。
/** * 绑定生命周期 */ <T> LifecycleTransformer<T> bindToLife();
这个bindToLife()是自定义的名字,这里就叫做bindToLife好了。
这个接口是自己定义的一个接口,我让Fragment来继承这个接口。
这个返回的是一个LifecycleTransformer<T>,这个官方的一个类。而且这里使用了泛型,更加通用了。
2.4.在自己的Fragment中实现这个接口函数。
/** * 绑定生命周期 */ @Override public <T> LifecycleTransformer<T> bindToLife() { return bindUntilEvent(FragmentEvent.DESTROY); }
这里调用了官方的一个bindUntilEvent的方法,以此函数来绑定生命周期。
这里的FragmentEvent.DESTROY,顾名思义,就是当Fragment销毁的时候,自动解除订阅关系。
注意:这里使用了FragmentEvent类,其中的CREATE/START/RESUME/PAUSE/STOP/DESTROY
分布对应生命周期内的方法。使用bindUntilEvent指定在哪个生命周期方法调用示取消订阅。
2.5.在请求API函数的时候,执行自己写的bindToLife()
调用Observable<T>.compose(执行接口中的bindToLife())
compose里面的东西应该是:LifecycleTransformer<T>。
3.对于Rxlifecycle的理解
3.1.使用原因就不用多说了,解决RxJava导致的内存泄漏。
3.2.因为activity和fragment控制切换线程的时候,引用没有清除干净,所以就把手脚着重于activity和fragment的
生命周期了,就是说,如果你的活动如果碰到意外或者用户主动销毁,那么也断开订阅,就是订阅的生命周期
和活动的生命周期已经融为一体了,那就不用担心再发生内存泄漏了,所以这种绑定生命周期的方法是从根本
上解决了内存泄漏。感觉没有更好的方法解决了。
3.3.其实官方为了两种解决方案。
一种是手动取消订阅,我不知道怎么用,也没有实战过。
这里提供一下大神的文章:RxAndroid之Rxlifecycle使用。
手动设置在activity onPause的时候取消订阅。
private static final String TAG = "RxLifecycle"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "onCreate()"); setContentView(R.layout.activity_main); Observable.interval(1, TimeUnit.SECONDS) .doOnUnsubscribe(new Action0() { @Override public void call() { Log.i(TAG, "Unsubscribing subscription from onCreate()"); } }) //Note:手动设置在activity onPause的时候取消订阅 .compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE)) .subscribe(new Action1<Long>() { @Override public void call(Long num) { Log.i(TAG, "Started in onCreate(), running until onPause(): " + num); } }); }
手动设置在activity的onDestroy的时候取消订阅。
@Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume()"); // `this.<Long>` is necessary if you‘re compiling on JDK7 or below. // If you‘re using JDK8+, then you can safely remove it. Observable.interval(1, TimeUnit.SECONDS) .doOnUnsubscribe(new Action0() { @Override public void call() { Log.i(TAG, "Unsubscribing subscription from onResume()"); } }) //Note:手动设置在activity onDestroy的时候取消订阅 .compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Action1<Long>() { @Override public void call(Long num) { Log.i(TAG, "Started in onResume(), running until in onDestroy(): " + num); } }); }
自动设置取消订阅,默认在onStart的时候调用,在onStop的时候取消订阅。
@Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart()");// Using automatic unsubscription, this should determine that the correct time to // unsubscribe is onStop (the opposite of onStart). Observable.interval(1, TimeUnit.SECONDS) .doOnUnsubscribe(new Action0() { @Override public void call() { Log.i(TAG, "Unsubscribing subscription from onStart()"); } }) //Note:bindToLifecycle的自动取消订阅示例,因为是在onStart的时候调用,所以在onStop的时候自动取消订阅 .compose(this.<Long>bindToLifecycle()) .subscribe(new Action1<Long>() { @Override public void call(Long num) { Log.i(TAG, "Started in onStart(), running until in onStop(): " + num); } }); }