¿Fuga de memoria en android.os.Message y / o Handler.removeCallback?
Tengo una actividad que se parece a la siguiente:
class MyActivity extends Activity { Runnable refreshTimer = new Runnable() { public void run() { refresh(); } }; protected onCreate(...) { handler.postAtTime(refreshTimer, ...); } protected onDestroy() { handler.removeCallbacks(refreshTimer); } protected void refresh() { ... } }
Después de llamarse onDestroy, todavía hay mensajes en MessageQueue de la actividad que contienen referencias a MyActivity $ 0 (la actualización Runnable) por alguna razón. Debido a que MyActivity $ 0 tiene una referencia implícita a MyActivity, esto provoca una pérdida de memoria del contexto MyActivity.
El resultado de merge_shortest_paths para android.app.Activity excluyendo phantom, soft, weak, etc referencias usando Eclipse Memory Analyzer Tool:
(El código fuente anterior es una simplificación de la relación de objeto real mostrada en el volcado MAT)
¿No debería llamar a removeCallbacks quitar cualquier referencia a los objetos ejecutables de la cola? ¿Por qué estoy filtrando los contextos?
Algo para probar:
De acuerdo con los documentos Android:
OnDestroy : La última llamada que reciba antes de destruir su actividad. Esto puede suceder ya sea porque la actividad está terminando (alguien llamó finish () en ella o porque el sistema está destruyendo temporalmente esta instancia de la actividad para ahorrar espacio). Puede distinguir estos dos escenarios con el método isFinishing ().
Cuando sale de su actividad, parece que aún hay un montón de mensajes en cola y el contexto para anular el registro no está invocando la cancelación de la devolución de llamada.
Lo que debe hacer es anular el registro de su ejecución en onPause : Esta devolución de llamada se utiliza principalmente para guardar cualquier estado persistente de la actividad de edición, para presentar un "editar en el lugar" modelo para el usuario y asegurarse de que no se pierde nada si no hay suficientes recursos Para iniciar la nueva actividad sin primero matar a ésta. Este es también un buen lugar para hacer cosas como detener animaciones y otras cosas que consumen una notable cantidad de CPU con el fin de hacer el cambio a la siguiente actividad tan rápido como sea posible, o para cerrar los recursos que son de acceso exclusivo, como la cámara.
Normalmente, un Receptor o Runnable "Programado" se registrará en onResume y se anulará el registro en onPause para un mejor emparejamiento del ciclo de vida
Sin ver lo que está haciendo en la actualización, es difícil decirlo, podría estar goteando debido a las referencias de actividad que son ámbito de actividad referenciado en el método de actualización.