Android distrugge attività, uccide processi


117

Ciao mi chiedo come stia Android gestendo la memoria e non riesco a trovare una risposta precisa da nessuna parte. Supponiamo che io abbia un'applicazione con 5 attività sullo stack di attività corrente (4 vengono arrestate e 1 viene ripristinata), non vi è alcun servizio connesso. Premo il pulsante HOME in modo che tutte le mie attività vengano interrotte. Avvio qualche altra applicazione che consuma memoria e la memoria complessiva del dispositivo inizia a essere bassa. E la domanda è

... Cosa accadrà alla mia domanda?

  1. Il sistema può distruggere solo una o alcune delle mie attività per recuperare la memoria?
  2. Il sistema interromperà l'intero processo della mia domanda? Tutte le attività verranno distrutte bene?
  3. Cosa succederà quando torno alla mia applicazione quando è stata completamente interrotta? Partirà dall'inizio (come il primo avvio) o proverà a ripristinare le attività allo stato precedente / se sì - è solo quella in cima alla pila o tutte?

AGGIORNARE:

Prima di porre questa domanda, ho visto il ciclo di vita delle attività alcune volte ma non ha risposte alle mie domande. Ho fatto dei test e ho delle risposte. "Interrompi processo" in DDMS era un indizio per il test.

Non ho testato la risposta per la domanda 1, ma come dice la guida:

Se un'attività viene sospesa o interrotta, il sistema può eliminare l'attività dalla memoria chiedendole di terminare o semplicemente interrompendo il processo.

Sembra che una o più delle attività possano essere distrutte delicatamente (con il metodo onDestroy) senza interrompere il processo. Riceverai semplicemente (onCreate + bundle) quando tornerai da loro.

Risposta alla domanda 2:

SÌ. Generalmente il sistema interrompe l'intero processo, ciò significa che tutti i dati, comprese le attività e i campi statici, vengono distrutti. Questo NON è fatto bene - non otterrai onDestroy o finialize () per nessuna delle tue attività sospese / interrotte. Questo è il motivo per cui saveInstanceState () viene chiamato appena prima del metodo onPause. onPause è fondamentalmente l'ultimo metodo in cui dovresti salvare qualcosa perché dopo questo metodo non potresti mai vedere onStop o onDestroy. Il sistema può semplicemente uccidere il processo distruggendo tutti i tuoi oggetti, qualunque cosa contengano e qualunque cosa stiano facendo.

Risposta alla domanda 3:

Cosa succederà quando torni a un'applicazione interrotta?

  • Prima di Android 2.2, l'applicazione partirà dall'inizio, con attività di avvio.
  • A partire dalla versione 2.2, il sistema ripristinerà lo stato dell'applicazione precedente. Cosa significa? Significa che l'ultima attività visibile verrà ricreata (onCreate + bundle). Cosa succederà con lo stack di attività? Stack va bene ma tutte le attività su di esso sono morte. Ognuno di essi verrà ricreato (onCreate + bundle) quando ci torni con il pulsante Indietro. C'è un'altra cosa su questo:

Normalmente, il sistema cancella un'attività (rimuove tutte le attività dallo stack sopra l'attività di root) in determinate situazioni quando l'utente seleziona nuovamente quell'attività dalla schermata principale. In genere, questo viene fatto se l'utente non ha visitato l'attività per un certo periodo di tempo, ad esempio 30 minuti.

Conclusione?

  1. Non pensare che i problemi di rotazione delle attività di gestione possano essere risolti da android: configChanges = "orientamento". Quando lo fai, avrai molti altri problemi di cui non sei nemmeno a conoscenza.
  2. Prova la tua applicazione con DDMS - Pulsante Interrompi processo. Guarda questo
  3. Fai attenzione quando usi variabili statiche. Non pensare che quando li hai inizializzati nell'attività 1, li avrai inizializzati nell'attività 2. L'unico posto sicuro per inizializzare la statistica globale sarebbe la classe Application.
  4. Ricorda che potresti non vedere mai onStop o onDestroy. Chiudi file / database, ferma i downloader in onPause. Quando vuoi che l'app faccia qualcosa in BG, usa il servizio in primo piano.

Sarebbe così ... Spero di aver aiutato con il mio essey :)


Per tua supposizione, queste 5 attività provengono dalla stessa app o da più app diverse?
Dumbfingers

1
"Ho un'applicazione con 5 attività nello stack di attività corrente" Ovviamente provengono tutte dalla mia stessa applicazione di processo.
Marco

4
Grazie anche questa era esattamente la mia domanda ... La tua domanda e le risposte mi hanno aiutato un po '.
craigrs84


@Mark: questo problema è stato risolto ora? E se lo fosse?
Ameer Moaaviah

Risposte:


30

Per prima cosa, dai un'occhiata a questo:

img1

onPause () Chiamato quando il sistema sta per iniziare a riprendere un'attività precedente. In genere viene utilizzato per eseguire il commit delle modifiche non salvate sui dati persistenti, interrompere le animazioni e altre cose che potrebbero consumare la CPU, ecc. Le implementazioni di questo metodo devono essere molto rapide perché l'attività successiva non verrà ripresa fino al ritorno di questo metodo. Seguito da onResume () se l'attività ritorna in primo piano o da onStop () se diventa invisibile all'utente.

onStop () Chiamato quando l'attività non è più visibile all'utente, perché un'altra attività è stata ripresa e copre questa. Ciò può accadere perché una nuova attività viene avviata, una esistente viene portata di fronte a questa o questa viene distrutta. Seguito da onRestart () se questa attività sta tornando per interagire con l'utente, o onDestroy () se questa attività sta scomparendo.

Così, quando si preme il tasto "HOME" sul dispositivo, l'attività di primo piano corrente viene messa in onPause()poi onStop(), gli altri 4 dovrebbe rimanereonStop()

Secondo i documenti di Google:

  • Se un'attività in primo piano sullo schermo (in cima allo stack), è attiva o in esecuzione.
  • Se un'attività ha perso il focus ma è ancora visibile (ovvero, una nuova attività non a grandezza naturale o trasparente ha il focus sulla tua attività), viene messa in pausa. Un'attività sospesa è completamente attiva (mantiene tutte le informazioni sullo stato e sui membri e rimane collegata al window manager), ma può essere interrotta dal sistema in situazioni di memoria estremamente ridotta.
  • Se un'attività è completamente oscurata da un'altra attività, viene interrotta. Conserva ancora tutte le informazioni sullo stato e sui membri, tuttavia, non è più visibile all'utente, quindi la sua finestra è nascosta e verrà spesso interrotta dal sistema quando la memoria è necessaria altrove.
  • Se un'attività viene sospesa o interrotta, il sistema può eliminare l'attività dalla memoria chiedendole di terminare o semplicemente interrompendo il processo. Quando viene visualizzato di nuovo per l'utente, deve essere completamente riavviato e riportato allo stato precedente.

E, per il ciclo di vita del processo:

Ciclo di vita del processo 3. Un'attività in background (un'attività che non è visibile all'utente ed è stata sospesa) non è più critica, quindi il sistema può terminare in sicurezza il suo processo per recuperare la memoria per altri processi visibili o in primo piano. Se il suo processo deve essere terminato, quando l'utente torna all'attività (rendendola nuovamente visibile sullo schermo), il suo metodo onCreate (Bundle) verrà chiamato con il savedInstanceState che aveva precedentemente fornito in onSaveInstanceState (Bundle) in modo che può riavviarsi nello stesso stato in cui l'utente l'ha lasciato l'ultima volta.

Tutte le citazioni sopra provengono da: Riferimento per sviluppatori Android: attività

È confermato che il sistema può distruggere le attività non attive e riciclare le memorie quando si lanciano alcune applicazioni che consumano memoria. E puoi implementare like: isFinishing()nella tua attività e quindi utilizzare il pulsante "kill" in DDMS per rilevare quale delle tue attività viene interrotta dal sistema. Ma immagino che il sistema distruggerà prima il più vecchio. Tuttavia non ha senso mantenere altre attività quando l '"attività di lancio" è stata riciclata.

AGGIORNARE

Ecco alcune opinioni che ho trovato da qui :

Stato interrotto

Quando un'attività non è visibile, ma è ancora in memoria, diciamo che è in uno stato interrotto. L'attività interrotta potrebbe essere riportata in primo piano per diventare di nuovo un'attività di corsa. Oppure potrebbe essere distrutto e rimosso dalla memoria.

Il sistema mantiene le attività in uno stato interrotto perché è probabile che l'utente voglia ancora tornare a quelle attività presto e riavviare un'attività interrotta è molto più economico che avviare un'attività da zero. Questo perché abbiamo già tutti gli oggetti caricati in memoria e dobbiamo semplicemente portarli tutti in primo piano.

Le attività interrotte possono essere rimosse dalla memoria in qualsiasi momento.


4
La documentazione è abbastanza confusa su questo argomento, tuttavia solo un intero processo può essere ucciso, non singoli componenti (attività, servizi, ecc.). Vedi: stackoverflow.com/questions/7536988/...
greg7gkb

Questa domanda dovrebbe essere aggiornata con le informazioni nel link del commento @ greg7gkb, è fuorviante
Luke De Feo

1

Il sistema può distruggere solo una o alcune delle mie attività per recuperare la memoria?

Sì. Android interrompe le attività in esecuzione in background quando è necessaria la memoria. Ucciderne uno o tutti potrebbe dipendere da alcune condizioni. Per un'istanza messa in pausa o interrotta può far sì che Android interrompa un'attività o un processo stesso. Qui sotto Activity Lifecycle puoi ottenere i seguenti punti. Ti consiglio di leggere completamente quella pagina. Sicuramente chiarirà i tuoi dubbi.

Se un'attività ha perso il focus ma è ancora visibile (ovvero, una nuova attività non a grandezza naturale o trasparente ha il focus sulla tua attività), viene messa in pausa. Un'attività sospesa è completamente attiva (mantiene tutte le informazioni sullo stato e sui membri e rimane collegata al window manager), ma può essere interrotta dal sistema in situazioni di memoria estremamente ridotta.

Se un'attività è completamente oscurata da un'altra attività, viene interrotta. Conserva ancora tutte le informazioni sullo stato e sui membri, tuttavia, non è più visibile all'utente, quindi la sua finestra è nascosta e verrà spesso interrotta dal sistema quando la memoria è necessaria altrove.

Se un'attività viene sospesa o interrotta, il sistema può eliminare l'attività dalla memoria chiedendole di terminare o semplicemente interrompendo il processo. Quando viene visualizzato di nuovo per l'utente, deve essere completamente riavviato e riportato allo stato precedente.


Il sistema interromperà l'intero processo della mia domanda? Tutte le attività verranno distrutte bene?

L'attività riguarda un individuo mentre il processo riguarda un gruppo di attività. Guarda di nuovo il terzo punto sopra che uccide il processo come accennato.


Cosa succederà quando torno alla mia applicazione quando è stata completamente interrotta?

È simile al riavvio. Anche in questo caso il terzo punto ti darà alcune risposte similiWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Ottieni altre informazioni sugli oggetti relativi alla memoria qui .

Modifica:
tutte le attività in un'applicazione vengono eseguite in un unico processo. Quindi, quando un processo viene terminato, tutte le attività, non importa 5 o 10, verranno terminate, ovvero riavviate. Il riavvio provocherà l'avvio dell'applicazione dall'inizio senza stati salvati.


2
Ho visto Activity Lifecycle almeno 5 volte ma non risponde alle mie domande. Quello che hai detto significherebbe quando il processo della mia app viene interrotto: quando torno all'app, viene ripristinato lo stato precedente. Quindi quando ho interrotto 5 attività .. sono morte tutte (invocata da onDestroy) quando il processo è stato interrotto? Quando sono tornato alla mia app tutte le attività sono state ripristinate (onCreate + bundle) o solo quella in cima allo stack (visibile all'utente)?
Marco

1
Tutte le attività in un'applicazione vengono eseguite in un unico processo. Quindi, quando un processo viene terminato, tutte le attività, non importa 5 o 10, verranno terminate, ovvero riavviate. Il riavvio provocherà l'avvio dell'applicazione dall'inizio senza stati salvati ..
Vinay

1
Quasi vero, ma non per 2.2 e versioni successive. Vedi il mio AGGIORNAMENTO nella parte superiore della pagina.
Marco

1
No, questo non è vero e non è mai stato vero. E 'di confusione sulla base dei documenti, ma vedere: stackoverflow.com/questions/7536988/...
greg7gkb

2
@JJPA Android non può distruggere singole attività per recuperare la memoria, distrugge solo i processi. Vedi questa risposta di Dianne Hackbor, membro del core team di Android coinvolto nell'implementazione "out of memory killer": stackoverflow.com/a/7576275/1290264 .
bcorso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.