本文从https://blog.csdn.net/mq2553299/article/details/78927617截取了一部分,具体的r实现原理可以参看原来的文章
随着RxJava及RxAndroid的逐渐推广,使用者越来越多,但是有一个问题,RxJava的使用不当极有可能会导致内存泄漏。
比如,使用RxJava发布一个订阅后,当Activity被finish,此时订阅逻辑还未完成,如果没有及时取消订阅,就会导致Activity无法被回收,从而引发内存泄漏。
目前网上对RxJava的内存泄漏有几种方案:
1、通过封装,手动为RxJava的每一次订阅进行控制,在指定的时机进行取消订阅;
2、使用 Daniel Lew 的 RxLifecycle ,通过监听Activity、Fragment的生命周期,来自动断开subscription以防止内存泄漏。
笔者上述两种方式都使用过,RxLifecycle显然对于第一种方式,更简单直接,并且能够在Activity/Fragment容器的指定生命周期取消订阅,实在是好用。
依赖并使用RxLifecycle
1、添加依赖
首先在build.gradle文件中添加依赖:
compile'com.trello.rxlifecycle2:rxlifecycle:2.2.1'compile'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'compile'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
1
2
3
2、配置Activity/Fragment容器
Activity/Fragment需继承RxAppCompatActivity/RxFragment,目前支持的有如下:
代码如下:
//只需要继承即可public class MainActivity extends RxAppCompatActivity {......}
1
2
3
4
5
3、使用compose操作符绑定容器生命周期
有两种方式:
3.1 使用bindToLifecycle()
以Activity为例,在Activity中使用bindToLifecycle()方法,完成Observable发布的事件和当前的组件绑定,实现生命周期同步。从而实现当前组件生命周期结束时,自动取消对Observable订阅,代码如下:
publicclassMainActivityextendsRxAppCompatActivity{@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);// 当执行onDestory()时, 自动解除订阅Observable.interval(1, TimeUnit.SECONDS) .doOnDispose(newAction() {@Overridepublicvoidrun()throwsException { Log.i(TAG,"Unsubscribing subscription from onCreate()"); } }) .compose(this.bindToLifecycle()) .subscribe(newConsumer() {@Overridepublicvoidaccept(Long num)throwsException { Log.i(TAG,"Started in onCreate(), running until onDestory(): "+ num); } }); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
3.2 使用bindUntilEvent()
使用ActivityEvent类,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分别对应生命周期内的方法。使用bindUntilEvent指定在哪个生命周期方法调用时取消订阅:
publicclassMainActivityextendsRxAppCompatActivity{@OverrideprotectedvoidonResume() {super.onResume(); Observable.interval(1, TimeUnit.SECONDS) .doOnDispose(newAction() {@Overridepublicvoidrun()throwsException { Log.i(TAG,"Unsubscribing subscription from onResume()"); } })//bindUntilEvent(),内部传入指定生命周期参数.compose(this.bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(newConsumer() {@Overridepublicvoidaccept(Long num)throwsException { Log.i(TAG,"Started in onResume(), running until in onDestroy(): "+ num); } }); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
以上,仅仅需要三步:依赖、继承、compose操作符,即可完成在容器的指定生命周期内,RxJava的自动取消订阅。