本菜雞對于Rxjava的感覺就是,簡便但上手難理解,熟練使用后越用越舒服呜笑。RXJava其實也用了很久了,但是之前一直沒有系統(tǒng)學(xué)習(xí)過彻犁,都是伴隨著OKGO來進行網(wǎng)絡(luò)請求而已叫胁,在其他的地方并沒有特別使用它,這段時間工作暫時沒安排汞幢,趁此機會趕緊系統(tǒng)的學(xué)習(xí)一波驼鹅。今天先記錄記錄一下,Rxjava2內(nèi)存泄漏的問題森篷。
首先我對RXJAVA內(nèi)存泄漏的理解是输钩,在線程和事件調(diào)度時,耗時任務(wù)在Activity/Fragment銷毀時還沒結(jié)束仲智,并且Activity/Fragment銷毀時又沒有去處理买乃,就會導(dǎo)致此Activity/Fragment無法被銷毀 從而泄漏內(nèi)存。
廢話不多說钓辆,上栗子
private var sec=60L
//在TestAty中使用Rxjava開啟一個耗時操作
Observable.intervalRange(0,sec,1,1,TimeUnit.SECONDS)
.map(object :Function<Long,Long>{
override fun apply(t: Long): Long {
return sec-t
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object :SimplerObserver2<Long>(this,true){
override fun onNext(t: Long) {
"${t}".logIt()
}
})
然后讓我們不斷的start這個Aty然后再finish的搞他
下面貼幾張圖來記錄內(nèi)存的變化
首先看一下App啟動初始的內(nèi)存占用(菜雞直接在項目里面開的測試Activity所以初始化內(nèi)存不小)
可以看到穩(wěn)定之后內(nèi)存大概就在75MB左右剪验,下面貼一張操作之后的圖
這都不用看棧實例了,很明顯側(cè)漏了一堆內(nèi)存前联,已經(jīng)爆到130MB的內(nèi)存了功戚。為了方便下面對比,我們還是看一下棧內(nèi)實例蛀恩。
可以看到棧內(nèi)一堆TestAty
那么怎么解決呢疫铜,我網(wǎng)上查了一下,很多都是說的是RxLifecycle這個東西去控制双谆,但是這東西需要你基類去繼承壳咕,這對于強迫癥來說簡直就是噩耗。相比之下我更推薦AutoDispose這個東西顽馋。
上面兩個都是需要額外依賴三方庫谓厘。感覺好像很復(fù)雜,但是我試了一下寸谜,通過
CompositeDisposable.dispose()
此方法來一樣能起到防止內(nèi)存?zhèn)嚷┑膯栴}竟稳,下面貼代碼
private var compositeDisable: CompositeDisposable?=null
private fun intervRange(){
Observable.intervalRange(0,sec,1,1,TimeUnit.SECONDS)
.map(object :Function<Long,Long>{
override fun apply(t: Long): Long {
return sec-t
}
})
.observeOn(AndroidSchedulers.mainThread())
//SimplerObserver2是封裝的一個觀察者
.subscribe(object :SimplerObserver2<Long>(this,true){
override fun onNext(t: Long) {
"${t}".logIt()
}
})
}
SimplerObserver2代碼如下
abstract class SimplerObserver2<T>(private val c:Context,private val isLoading:Boolean):Observer<T> {
override fun onError(e: Throwable) {
}
override fun onComplete() {
if (c is TestAty){
c.loadingDialog.dismiss()
}
}
//關(guān)鍵代碼,在OnSubscrib時將disposable添加當(dāng)Activity中的CompositeDisposable
override fun onSubscribe(d: Disposable) {
if (c is TestAty){
c.loadingDialog.show()
c.addDisable(d)
}
}
}
最后在Activity的ondestory()時
compositeDisable.dispose()
這樣就能取消activity的訂閱熊痴,下面我們再重復(fù)操作一下剛剛的操作看看效果如何
創(chuàng)建銷毀次數(shù)大概是剛剛的兩倍他爸,內(nèi)存消耗也從75MB漲到了85MB,看上去好像也泄漏了果善,那么看一下棧內(nèi)實例
沒有TestAty的實例了诊笤,說明已經(jīng)被銷毀了,也就是說TestAty沒有再內(nèi)存泄漏了巾陕。大家使用的話上面的CompositeDisposable和Add的方法可以寫在BaseAty中讨跟,方便使用
好了至此Rxjava內(nèi)存泄漏的問題我覺得是解決了,但是反復(fù)操作后從75MB到了85MB鄙煤,這是什么原因有大佬知道嗎晾匠。以上可以說是筆記,僅供參康梯刚,有不對的大佬發(fā)現(xiàn)了請指出凉馆。