2012-10-23 3 views
6

devo un'attività che è simile al seguente:Perdita di memoria in android.os.Message e/o Handler.removeCallback?

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() { ... } 
} 

Dopo OnDestroy si chiama, ci sono ancora messaggi nella MessageQueue della attività che contengono riferimenti a MyActivity $ 0 (l'aggiornamento Runnable) per qualche motivo. Poiché MyActivity $ 0 ha un riferimento implicito a MyActivity, ciò provoca una perdita di memoria del contesto MyActivity.

Il risultato di merge_shortest_paths per android.app.Activity escluso fantasma,, deboli, riferimenti ecc morbide con Eclipse Memory Analyzer Strumento: enter image description here

(Il codice sorgente sopra è una semplificazione del rapporto oggetto reale visualizzato nel la discarica MAT)

non dovrebbe chiamare removeCallbacks rimuovere tutti i riferimenti agli oggetti eseguibili dalla coda? Perché sto perdendo contesti?

risposta

2

qualcosa da provare:

Secondo la documentazione Android:

OnDestroy: L'ultima chiamata si riceve prima dell'attività è distrutto. Ciò può accadere sia perché l'attività sta finendo (qualcuno ha chiamato finitura() su di esso, o perché il sistema sta distruggendo temporaneamente questa istanza l'attività per risparmiare spazio. È possibile distinguere tra questi due scenari con il metodo isFinishing().

Quando si sta uscendo la vostra attività, sembra che ci sono ancora un sacco di messaggi in coda e il contesto per l'annullamento della registrazione non sta invocando la richiamata annullare

che cosa si dovrebbe fare è la registrazione del proprio eseguibile in onPause:. questo il callback è principalmente usato per salvare qualsiasi stato persistente che l'attività sta modificando, per presentare all'utente un modello "edit in place" e assicurarsi che nulla venga perso se non ci sono abbastanza risorse per iniziare w attività senza prima uccidere questo. Questo è anche un buon posto per fare cose come fermare le animazioni e altre cose che consumano una notevole quantità di CPU al fine di passare alla prossima attività il più velocemente possibile, o per chiudere le risorse che sono l'accesso esclusivo come la fotocamera.

Tipicamente un ricevitore o "programmata" Runnable registrerà nel onResume, e annullare la registrazione in onPause per una migliore ciclo di vita di accoppiamento

Senza vedere cosa si sta facendo in aggiornamento, è difficile da dire, potrebbe essere perde a causa di riferimenti di attività con ambito di attività a cui si fa riferimento nel metodo di aggiornamento.