代码之家  ›  专栏  ›  技术社区  ›  Daniel Benedykt

PhoneStateListener内存泄漏-Android

  •  1
  • Daniel Benedykt  · 技术社区  · 15 年前

    我运行了很多次我的应用程序后内存出现问题。

    java.lang.outOfMemoryError:位图大小超过了虚拟机预算

    我觉得我不知怎么地在泄漏内存,所以我做了一个dump hprof文件,并使用mat工具来确定出了什么问题。 事实证明,在运行了应用程序的5倍并退出之后,我发现了我的活动的5个实例和PhoneStateListener的5个实例。

    如果我取消对PhoneStateListener的调用,我就不再有这个问题了,我只看到我的活动的一个实例。

    问题是,我如何解决这个问题?

    谢谢

    丹尼尔


    这是我的代码:

    创建方法:

    telephonyManager.listen(mPhoneListener,
                    PhoneStateListener.LISTEN_SERVICE_STATE
                    | PhoneStateListener.LISTEN_SIGNAL_STRENGTH
                    | PhoneStateListener.LISTEN_CALL_STATE
                    | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                    | PhoneStateListener.LISTEN_DATA_ACTIVITY); 
    

    在活动类上:

    PhoneStateListener mPhoneListener = new PhoneStateListener() {
            public void onCallStateChanged(int state,
                    java.lang.String incomingNumber) {
            //do something
        }
    }
    

    OnDestroy方法:

    telephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);        
    mPhoneListener = null;
    
    3 回复  |  直到 12 年前
        1
  •  6
  •   Karim    15 年前

    OnDestroy不能保证被呼叫。来源: onDestroy Docs

    你应该试着在暂停时清理,然后在恢复时重新安装你需要的东西。这将有助于清除一些内存压力和泄漏。

        2
  •  6
  •   Jan    14 年前

    上面的答案不正确:OnDestroy()在这里不是问题,因为终止进程显然会释放所有内存和绑定。

    这里有一个非常重要的因素你必须考虑到。只有在系统进程中关联的绑定器对象释放后,才能释放在电话管理器中注册的绑定器。在正确注销侦听器之后,这可能需要很长时间,因为在系统进程中运行下一个GC之前,可能需要一段时间才能收回对象以及对侦听器的引用。

    当您在OnDestroy()中完成对其他对象的引用时,您能做的最好的事情就是手动删除它。

        3
  •  -1
  •   Chuchi    12 年前
    PhoneStateListener mPhoneListener = new PhoneStateListener() 
    { 
        public void onCallStateChanged(int state, java.lang.String incomingNumber) 
        { 
        //do something 
    
         telephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE); 
         mPhoneListener = null;
        } 
    }