Ciclo di vita degli oggetti statici Android


101

Sto creando un'applicazione per la ricerca di eventi, impostiamo i criteri di ricerca da una schermata e popola un'altra schermata, quindi l'utente può modificare i criteri di ricerca dalla terza schermata e passa alla quarta schermata.

Per ottenere il compito di cui sopra sto usando un oggetto statico che ricorda i valori dell'applicazione e non ho bisogno di fare nulla in più.

Ma temo se sul ciclo di vita degli oggetti statici in Android se la memoria insufficiente trovasse Android elimina gli oggetti statici ???

Poiché Android supporta il multitasking, se l'utente passa a un'altra applicazione e quando torna l'applicazione inizia a comportarsi in modo pazzo, l'oggetto statico viene rimosso quando è multi task ??? qualche idea ?? e suggerire anche di tenere l'oggetto statico tramite il metodo singleton è un approccio migliore ???

Risposte:


238

Iniziamo con un po 'di background: cosa succede quando avvii un'applicazione?
Il sistema operativo avvia un processo e gli assegna un ID processo univoco e alloca una tabella di processo. Un processo avvia un'istanza di DVM (Dalvik VM); Ogni applicazione viene eseguita all'interno di un DVM.
Un DVM gestisce lo scaricamento del caricamento delle classi, il ciclo di vita dell'istanza, il GC ecc.

Durata di una variabile statica: una variabile statica nasce quando una classe viene caricata dalla JVM e muore quando la classe viene scaricata.

Quindi, se crei un'applicazione Android e inizializzi una variabile statica, rimarrà nella JVM fino a quando non si verifica una delle seguenti condizioni:
1. la classe viene scaricata
2. la JVM si spegne
3. il processo muore

Si noti che il valore della variabile statica persisterà quando si passa a un'attività diversa di un'altra applicazione e nessuna delle tre precedenti si verifica. Se uno dei tre precedenti si verifica, l'elettricità statica perderà il suo valore.

Puoi testarlo con poche righe di codice:

  1. stampa la statica non inizializzata in onCreate della tua attività -> dovrebbe stampare null
  2. inizializza la statica. stampalo -> il valore non sarebbe nullo
  3. Premi il pulsante Indietro e vai alla schermata principale. Nota: la schermata Home è un'altra attività.
  4. Avvia di nuovo la tua attività -> la variabile statica non sarà nulla
  5. Termina il processo di candidatura da DDMS (pulsante di arresto nella finestra dei dispositivi).
  6. Riavvia la tua attività -> lo statico avrà valore nullo.

Spero che aiuti.


1
Voglio sapere perché perdo il valore del mio campo nell'oggetto applicazione se non è statico quando inizio una nuova attività, ad esempio dichiaro la pagina corrente variabile nell'oggetto applicazione e il suo valore ritorna sempre a zero quando apro una nuova attività
Mohammed Subhi Sheikh Quroush

quando chiamo super.onRestoreInstanceState (savedInstanceState); Perdo le mie variabili anche se sono statiche, qual è il problema?
Mohammed Subhi Sheikh Quroush

1
questa è una bella spiegazione (quindi no -1) ma è un po 'irrilevante: l'OP ha chiesto esplicitamente di "situazioni di memoria insufficiente" (stesso motivo per cui sono qui), dove per quanto ne so il sistema operativo potrebbe uccidere la VM e riavviarlo più tardi con gli stessi parametri, e questo caso ( SE è una cosa reale) non è coperto qui ...
Rick77

1
@suitianshi Penso che possiamo inizializzare le istanze statiche in Application.onCreate, perché anche se la nostra app va in background e il processo viene interrotto, non appena torniamo alla nostra app, la classe Application verrà istanziata e chiamerà i metodi del ciclo di vita corrispondenti ancora! anche se ho bisogno di conferma su questo, mi chiedo se potrebbe esserci qualche scenario in cui l'istanza statica inizializzata in Application.onCreate perde il suo valore?
Sarthak Mittal

1
Quello che mi manca qui è una spiegazione per "1. la classe è scaricata" - quando succederebbe? JVM scaricherà una classe se la memoria è insufficiente?
Stoefln

16

Bene, il pattern Singleton si basa anche sull'uso di variabili statiche, quindi in realtà saresti nella stessa posizione. Sebbene l'approccio statico possa funzionare la maggior parte delle volte, può accadere che in alcuni casi, quando la memoria è piena e un'altra attività è in primo piano prima che l'applicazione passi alla schermata successiva, il processo dell'attività potrebbe essere interrotto e si perdono i valori statici. Tuttavia, Android offre alcune opzioni per mantenere i valori tra gli stati o trasmetterli come:

  • utilizzando un Intent, potresti trasmettere i tuoi criteri di ricerca da attività a attività (simile a una richiesta Web http)
  • utilizzando le preferenze dell'applicazione, è possibile salvare i valori e recuperarli nell'attività che ne ha bisogno
  • utilizzando il database sqlite è possibile mantenerli in una tabella e recuperarli in seguito
  • se è necessario salvare solo lo stato dell'attività in modo che al riavvio i campi vengano riempiti con i valori precedentemente selezionati, è possibile implementare il metodo di attività onSaveInstanceState () - notare che questo non è consigliato per la persistenza degli stati tra le attività.

È possibile ottenere alcuni esempi di codice sull'utilizzo delle preferenze, degli intenti e del database sqlite osservando l' albero del codice sorgente aegis-shield nel codice Google o in altre applicazioni Android open source.


6

Dopo alcune ricerche, si scopre che usare Application per archiviare singleton non è un'idea eccezionale, a meno che tu non sia pronto a ricrearlo:

Non memorizzare i dati nell'oggetto dell'applicazione

quindi, sebbene la risposta accettata sia tecnicamente corretta, non fornisce tutte le informazioni.

Come suggerisce il collegamento sopra, se vuoi davvero restare con quel modello, devi essere pronto a verificare la presenza di null e ricreare i dati, se possibile.


3

@ r1k0 è proprio qui. La memorizzazione dei dati nei campi statici di una classe non persisterà da sola durante le uccisioni e i riavvii del processo dell'applicazione. Android interrompe regolarmente i processi (esecuzione di app) quando ha bisogno di memoria.

Secondo il documento Android: stato dell'attività ed espulsione dalla memoria ,

Il sistema non interrompe mai direttamente un'attività. Invece, uccide il processo in cui viene eseguita l'attività, distruggendo non solo l'attività ma anche tutto il resto in esecuzione nel processo.

È possibile salvare e ripristinare lo stato delle primitive e anche degli oggetti Serializable e Parcelable utilizzando i metodi seguenti. Questi vengono chiamati automaticamente durante il normale ciclo di vita dell'attività.

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

Quindi, se hai una classe che ha solo variabili statiche, puoi salvare lo stato di ogni campo in onSaveInstanceState () e ripristinarli in onRestoreInstanceState (). Quando Android termina il processo in cui è in esecuzione l'app, lo stato delle variabili verrà salvato e quando Android ripristina l'app, i valori verranno ripristinati in memoria nello stesso stato di prima.

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.