2009-12-29 13 views
26

Ho un'attività e chiamo il metodo finish() e l'attività non viene cancellata dalla memoria.Il metodo android finish() non cancella l'app dalla memoria

Dopo aver chiamato finish(), vedo che il metodo onDestroy() è stato eseguito correttamente (e ho cancellato tutte le mie variabili e cose lì).

Dovrebbe essere cancellato dalla memoria o è come funziona Android? Come ho capito, il LifeCycle of the Activity è finito.

E se mantiene l'app in memoria in modo che funzioni più velocemente la seconda volta che l'utente lo utilizza, che tipo di oggetti posso lasciare in memoria per riutilizzarli? Se ho capito bene, suppongo di chiarire tutto su onDestroy.

+0

"Ho un'attività e chiamo il metodo finish() e l'attività non viene cancellata dalla memoria." - come, * precisamente *, hai determinato questo? – CommonsWare

+2

Se si usa DDMS da eclipse, è possibile eseguire il debug per assicurarsi che venga eseguito su onDestroy() e dopo di ciò è ancora possibile vedere il processo nel dispositivo e si può anche vedere la dimensione dell'heap che è stata acquisita, e si può scaricare la memoria analizzare. Se non mi sbaglio, significa che è ancora in memoria, giusto? –

risposta

31

Android mantiene i processi in giro nel caso in cui l'utente desideri riavviare l'app, questo rende più veloce la fase di avvio. Il processo non farà nulla e se la memoria deve essere recuperata, il processo verrà ucciso. Non ti preoccupare :)

+1

Questo vale anche per "sottoattività", significa se non è l'ultima attività aperta nella mia app? Dire: se apro l'attività B dall'attività A, quindi B.finish(), Android alla fine manterrà B in memoria e alla fine visualizzerei anche B nel mio hprof dump (nel caso in cui Android non necessitasse di recuperare la memoria per altrove)? –

+0

Sì, l'attività B sarà ancora in memoria. L'attività B verrà rimossa solo se Android ha bisogno di memoria per qualcos'altro. – ChuongPham

+0

"Non ti preoccupare di inviare l'app allo sfondo invece di rimuoverla completamente dalla memoria?" Sei un programmatore serio? Che ne dici di Bank o di altre applicazioni fragili per la sicurezza? – TomeeNS

6

Una volta chiamato onDestroy(), la tua attività è condannata. Periodo.

Detto questo, il processo (e quindi lo spazio degli indirizzi) assegnato alla vostra applicazione potrebbe ancora essere utilizzato da un'altra parte della vostra applicazione - un'altra attività o servizio. È anche possibile che il tuo processo sia vuoto e che il sistema operativo non sia ancora riuscito a riprenderlo; non è istantaneo

Vedere il documento Process Lifecycle per ulteriori informazioni:
http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle

Indipendentemente da ciò, se la vostra attività è rilanciata, dovrà passare attraverso l'intera sequenza di avvio di nuovo, a partire da onCreate(). Non dare per scontato che nulla possa essere riutilizzato implicitamente.

+0

Credo che questo non sia completamente vero. Non credo che l'attività sia fatale, perché ci sono modi per filtrare la memoria e quindi l'attività vivrà per sempre. –

+0

Anche se un'attività perde memoria, quando il sistema operativo uccide il processo, la memoria verrà recuperata. Proprio come quando si termina un processo su un sistema operativo desktop. –

1

Secondo this presentazione da parte di Google I/O 2008, Fine dovrebbe causare anche il processo per essere ucciso, ma ho scritto una rapida applicazione per verificare questa e su Android 1.5 lo fa non.

Come ha detto Romain (che per inciso è un ingegnere di UI Toolkit per Android), il processo si limiterà a non fare nulla, quindi non c'è nulla di cui preoccuparsi.

10

Provare a utilizzare

System.exit (0);

+0

risparmi il mio tempo grazie :) – HarrY

4

Se è necessario chiudere l'applicazione dall'attività secondaria, è possibile suggerire di farlo in modo tale: 1) dall'attività Attività di chiamata B come startActivityForResult (intent, REQUEST_CODE);

Intent intent = new Intent() 
      .setClass(ActivityA.this, ActivityB.class); 
      startActivityForResult(intent, REQUEST_CODE); 

2) nell'attività A si dovrebbe aggiungere il metodo:

protected void onActivityResult(int requestCode, int resultCode, 
     Intent data) { 
    if (requestCode == REQUEST_CODE) { 
     if (resultCode == RESULT_CLOSE_APPLICATION) { 
      this.finish(); 
     } 
    } 
} 

3) in attività di finitura B chiamata:

this.setResult(RESULT_CLOSE_APPLICATION); 
this.finish(); 
1

Come una soluzione rapida è possibile utilizzare il seguente per uccidere la tua app:

android.os.Process.killProcess(android.os.Process.myPid()); 

Ma non lo consiglierei d questo per le app commerciali perché va contro il modo in cui funziona il sistema di gestione della memoria Android.

23

Il modo migliore è utilizzare prima finish() e successivamente utilizzare System.exit(0) per cancellare variabili statiche. Ti darà dello spazio libero.

Un sacco di applicazioni lasciano processi di lavoro e variabili ciò che mi fa arrabbiare. Dopo 30 minuti di utilizzo della memoria è piena e devo eseguire Task Manager - Lvl 2 memoria chiara

Non è vero che è problemi di cousione l'ho provato per oltre 3 anni nelle mie app. Mai arrestarsi in modo anomalo o riavviare dopo l'uso Exit()

+2

Questo funziona anche per me . Ho avuto una situazione in cui stavo premendo il pulsante Indietro per uscire dall'app, per comportamento normale, e stava lasciando la memoria intorno. La prossima volta che ho iniziato, la memoria si è accumulata e, se l'ho fatto circa cinque volte, ho esaurito l'heap (24 MB sul dispositivo di test). finish() da solo non stava facendo il lavoro. Ho il sospetto che l'attività di Splash che uso per far sapere all'utente che avremo ragione potrebbe aver impedito in qualche modo alla memoria di essere recuperata all'uscita. Sembra poco utile utilizzare uno strumento così rozzo, ma quando si chiude l'app, qual è la differenza? – Carl

+0

Grazie, questa risposta ha risolto il mio problema. –

+2

La mia app di gioco utilizza 225 MB alla prima esecuzione. Dopo aver usato finish() e riavviato, usa questa volta 400MB, con un funzionamento molto più lento (il mio Samsung Galaxy Tab S2 ha un heap di 524M). Su altri dispositivi meno ricchi si blocca solo con un errore di "esaurimento della memoria" nella seconda esecuzione. L'uso di 'System.exit (0)' dopo 'finish()' sembra risolvere questo problema. Ho notato che "finish()" non interrompe immediatamente l'esecuzione del codice, poiché "System.exit (0)" viene ancora raggiunto quando viene posizionato dopo "finish()". Tuttavia, "System.exit (0)" sembra arrestare il codice eseguito sulla sua linea. – Androidcoder

Problemi correlati