本文從https://blog.csdn.net/mq2553299/article/details/78927617截取了一部分,具體的r實(shí)現(xiàn)原理可以參看原來的文章
隨著RxJava及RxAndroid的逐漸推廣,使用者越來越多,但是有一個(gè)問題,RxJava的使用不當(dāng)極有可能會導(dǎo)致內(nèi)存泄漏。
比如,使用RxJava發(fā)布一個(gè)訂閱后,當(dāng)Activity被finish,此時(shí)訂閱邏輯還未完成,如果沒有及時(shí)取消訂閱,就會導(dǎo)致Activity無法被回收,從而引發(fā)內(nèi)存泄漏。
目前網(wǎng)上對RxJava的內(nèi)存泄漏有幾種方案:
1、通過封裝,手動為RxJava的每一次訂閱進(jìn)行控制,在指定的時(shí)機(jī)進(jìn)行取消訂閱;?
2、使用?Daniel Lew?的?RxLifecycle?,通過監(jiān)聽Activity、Fragment的生命周期,來自動斷開subscription以防止內(nèi)存泄漏。
筆者上述兩種方式都使用過,RxLifecycle顯然對于第一種方式,更簡單直接,并且能夠在Activity/Fragment容器的指定生命周期取消訂閱,實(shí)在是好用。
首先在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
Activity/Fragment需繼承RxAppCompatActivity/RxFragment,目前支持的有如下:

代碼如下:
//只需要繼承即可public class MainActivity extends RxAppCompatActivity {......}
1
2
3
4
5
有兩種方式:
3.1 使用bindToLifecycle()
以Activity為例,在Activity中使用bindToLifecycle()方法,完成Observable發(fā)布的事件和當(dāng)前的組件綁定,實(shí)現(xiàn)生命周期同步。從而實(shí)現(xiàn)當(dāng)前組件生命周期結(jié)束時(shí),自動取消對Observable訂閱,代碼如下:
publicclassMainActivityextendsRxAppCompatActivity{@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);// 當(dāng)執(zhí)行onDestory()時(shí), 自動解除訂閱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分別對應(yīng)生命周期內(nèi)的方法。使用bindUntilEvent指定在哪個(gè)生命周期方法調(diào)用時(shí)取消訂閱:
publicclassMainActivityextendsRxAppCompatActivity{@OverrideprotectedvoidonResume() {super.onResume();? ? ? ? Observable.interval(1, TimeUnit.SECONDS)? ? ? ? ? ? .doOnDispose(newAction() {@Overridepublicvoidrun()throwsException {? ? ? ? ? ? ? ? ? ? Log.i(TAG,"Unsubscribing subscription from onResume()");? ? ? ? ? ? ? ? }? ? ? ? ? ? })//bindUntilEvent(),內(nèi)部傳入指定生命周期參數(shù).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操作符,即可完成在容器的指定生命周期內(nèi),RxJava的自動取消訂閱。