Android Rxjava2.x内存泄漏问题

2019-12-03  本文已影响0人  宇智波_佐星

本菜鸡对于Rxjava的感觉就是,简便但上手难理解,熟练使用后越用越舒服。RXJava其实也用了很久了,但是之前一直没有系统学习过,都是伴随着OKGO来进行网络请求而已,在其他的地方并没有特别使用它,这段时间工作暂时没安排,趁此机会赶紧系统的学习一波。今天先记录记录一下,Rxjava2内存泄漏的问题。


首先我对RXJAVA内存泄漏的理解是,在线程和事件调度时,耗时任务在Activity/Fragment销毁时还没结束,并且Activity/Fragment销毁时又没有去处理,就会导致此Activity/Fragment无法被销毁 从而泄漏内存。



废话不多说,上栗子

 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的搞他



下面贴几张图来记录内存的变化
首先看一下App启动初始的内存占用(菜鸡直接在项目里面开的测试Activity所以初始化内存不小)



可以看到稳定之后内存大概就在75MB左右,下面贴一张操作之后的图

这都不用看栈实例了,很明显侧漏了一堆内存,已经爆到130MB的内存了。为了方便下面对比,我们还是看一下栈内实例。



可以看到栈内一堆TestAty

那么怎么解决呢,我网上查了一下,很多都是说的是RxLifecycle这个东西去控制,但是这东西需要你基类去继承,这对于强迫症来说简直就是噩耗。相比之下我更推荐AutoDispose这个东西。

上面两个都是需要额外依赖三方库。感觉好像很复杂,但是我试了一下,通过
CompositeDisposable.dispose()
此方法来一样能起到防止内存侧漏的问题,下面贴代码

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()
        }
    }

//关键代码,在OnSubscrib时将disposable添加当Activity中的CompositeDisposable
    override fun onSubscribe(d: Disposable) {
        if (c is TestAty){
            c.loadingDialog.show()
            c.addDisable(d)
        }
    }
}

最后在Activity的ondestory()时

compositeDisable.dispose()

这样就能取消activity的订阅,下面我们再重复操作一下刚刚的操作看看效果如何



创建销毁次数大概是刚刚的两倍,内存消耗也从75MB涨到了85MB,看上去好像也泄漏了,那么看一下栈内实例



没有TestAty的实例了,说明已经被销毁了,也就是说TestAty没有再内存泄漏了。大家使用的话上面的CompositeDisposable和Add的方法可以写在BaseAty中,方便使用

好了至此Rxjava内存泄漏的问题我觉得是解决了,但是反复操作后从75MB到了85MB,这是什么原因有大佬知道吗。以上可以说是笔记,仅供参康,有不对的大佬发现了请指出。

上一篇下一篇

猜你喜欢

热点阅读