2009-12-22 4 views
1

J'ai un problème avec la mémoire après avoir couru plusieurs fois mon application.PhoneStateListener fuite de mémoire - android

java.lang.OutOfMemoryError: la taille du bitmap dépasse le budget VM

Je me dis que je suis en quelque sorte une fuite de mémoire, donc je l'ai fait un fichier HPROF DUMP et utilisé l'outil MAT pour savoir ce qui était faux. Il se trouve que, après avoir exécuté 5 fois l'application et quitter, je trouve 5 instances de mon activité et 5 instances de PhoneStateListener.

Si je supprime l'appel à PhoneStateListener, je n'ai plus ce problème et je vois juste 1 instance de mon activité. La question est, comment puis-je résoudre ce problème?

Merci

Daniel


Voici mon code:

méthode 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); 

sur la classe d'activité:

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

sur la méthode de OnDestroy:

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

Répondre

6

OnDestroy n'est pas garanti pour obtenir appelé. Source: onDestroy Docs

Vous devriez essayer de nettoyer sur onPause, puis sur Restaurez le matériel dont vous avez besoin. Cela aidera à nettoyer la mémoire et les fuites.

+0

merci. Ce n'était pas la source du problème que j'avais, mais oui, c'est la bonne réponse à ma question. –

+0

Alors, que faire si je veux que mon application écoute les appels entrants pendant que le service est actif? Appel de mTelMan.listen (mCustomCallStateListener, PhoneStateListener.LISTEN_CALL_STATE); En quelque sorte, le cycle de vie et le service ne sont pas détruits correctement. Est-ce que cela a de l'importance que mon écouteur personnalisé obtienne un autre objet dans le constructeur, alors je me retrouve dans une situation de fuite de mémoire? – Ewoks

+0

Si onDestroy n'est pas appelé, cela signifie que le processus a été brutalement interrompu. Dans ce cas, les fuites de mémoire sont résolues, la réponse @Jan semble correcte – lelloman

6

La réponse ci-dessus n'est pas correcte: onDestroy() n'est pas un problème ici car la suppression du processus libérera évidemment toute la mémoire et les classeurs.

Il y a un élément très important à prendre en compte ici. Le classeur enregistré auprès du gestionnaire de téléphonie ne sera libéré qu'après la libération de l'objet classeur associé dans le processus système. Cela peut être long après la désinscription correcte de l'écouteur, car cela peut prendre un certain temps avant que le prochain cycle GC dans le processus système récupère l'objet et avec cela la référence à votre écouteur. La meilleure chose à faire est de supprimer manuellement les références de l'écouteur à d'autres objets lorsque vous en avez fini avec onDestroy().

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

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

OnCallStateChanged est appelée une seule fois dans ce cas. – pocorall