Утечка памяти PhoneStateListener - Android - PullRequest
1 голос
/ 22 декабря 2009

У меня проблемы с памятью после многократного запуска моего приложения.

java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет виртуальной машины

Я полагаю, что каким-то образом у меня возникла утечка памяти, поэтому я создал файл DUMP HPROF и использовал инструмент MAT, чтобы выяснить, что не так. Оказывается, после 5-кратного запуска приложения и выхода из него я нахожу 5 экземпляров своей активности и 5 экземпляров PhoneStateListener.

Если я удалю вызов PhoneStateListener, у меня больше не будет этой проблемы, и я вижу только 1 экземпляр моей Деятельности.

Вопрос в том, как мне решить эту проблему?

Спасибо

Daniel


Вот мой код:

Метод OnCreate:

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 ]

6 голосов
/ 25 августа 2010

Ответ выше не верен: onDestroy () здесь не проблема, поскольку уничтожение процесса, очевидно, освободит всю память и связующие.

Здесь есть один очень важный элемент, который вы должны принять во внимание. Связыватель, зарегистрированный в диспетчере телефонии, будет освобожден только после освобождения связанного объекта связывания в системном процессе. Это может занять много времени после правильной отмены регистрации прослушивателя, поскольку может пройти некоторое время, прежде чем следующий запуск GC в системном процессе освободит объект и вместе с этим ссылку на слушателя.

Лучшее, что вы можете сделать, - это вручную удалить ссылки из слушателя на другие объекты, когда вы закончите с ним в onDestroy ().

6 голосов
/ 22 декабря 2009

onDestroy не гарантируется, что вам позвонят. Источник: onDestroy Docs

Вы должны попытаться очистить onPause, а затем onResume восстановите нужную информацию. Это поможет убрать некоторое давление памяти и утечки.

0 голосов
/ 21 марта 2012
PhoneStateListener mPhoneListener = new PhoneStateListener() 
{ 
    public void onCallStateChanged(int state, java.lang.String incomingNumber) 
    { 
    //do something 

     telephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE); 
     mPhoneListener = null;
    } 
}
...