美文网首页
Android Rxjava2.x内存泄漏问题

Android Rxjava2.x内存泄漏问题

作者: 宇智波_佐星 | 来源:发表于2019-12-03 11:24 被阅读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,这是什么原因有大佬知道吗。以上可以说是笔记,仅供参康,有不对的大佬发现了请指出。

    相关文章

      网友评论

          本文标题:Android Rxjava2.x内存泄漏问题

          本文链接:https://www.haomeiwen.com/subject/rrygwctx.html