RxLifecycle 解決rxjava引起的內(nèi)存泄露問題

本文從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í)在是好用。

依賴并使用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發(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的自動取消訂閱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容