Statischer Objektlebenszyklus für Android

101

Ich erstelle eine Ereignissuchanwendung. Wir legen Suchkriterien von einem Bildschirm in einem anderen Bildschirm fest, dann kann der Benutzer die Suchkriterien vom 3. Bildschirm aus bearbeiten und wechselt zum 4. Bildschirm.

Um die obige Aufgabe zu erfüllen, verwende ich ein statisches Objekt, das sich an die Werte rund um die Anwendung erinnert, und ich muss nichts extra tun.

Aber ich habe Angst, wenn über statische Objektlebenszyklus in Android, wenn wenig Speicher gefunden Android statische Objekte löschen?

Da Android Multitasking unterstützt, werden statische Objekte beim Multitasking entfernt, wenn der Benutzer zu einer anderen Anwendung wechselt und wenn der Benutzer zurückkommt. irgendeine Idee ?? und auch vorschlagen, statische Objekte über Singleton-Methode zu halten, ist ein besserer Ansatz?

D-Mann
quelle

Antworten:

238

Beginnen wir mit ein wenig Hintergrundwissen: Was passiert, wenn Sie eine Anwendung starten?
Das Betriebssystem startet einen Prozess und weist ihm eine eindeutige Prozess-ID zu und weist eine Prozesstabelle zu. Ein Prozess startet eine Instanz von DVM (Dalvik VM). Jede Anwendung wird in einem DVM ausgeführt.
Ein DVM verwaltet das Entladen von Klassen, das Entladen von Instanzen, den Instanzlebenszyklus, GC usw.

Lebensdauer einer statischen Variablen: Eine statische Variable entsteht, wenn eine Klasse von der JVM geladen wird, und stirbt, wenn die Klasse entladen wird.

Wenn Sie also eine Android-Anwendung erstellen und eine statische Variable initialisieren, bleibt diese in der JVM, bis eines der folgenden Ereignisse eintritt :
1. Die Klasse wird entladen.
2. Die JVM wird heruntergefahren
3. Der Prozess stirbt ab

Beachten Sie, dass der Wert der statischen Variablen erhalten bleibt, wenn Sie zu einer anderen Aktivität einer anderen Anwendung wechseln und keine der drei oben genannten Aktionen ausgeführt wird. Sollte einer der oben genannten drei Fälle eintreten, verliert die Statik ihren Wert.

Sie können dies mit ein paar Codezeilen testen:

  1. Drucken Sie die nicht initialisierte Statik in onCreate Ihrer Aktivität aus -> sollte null drucken
  2. Initialisieren Sie die statische. print it -> value wäre nicht null
  3. Drücken Sie die Zurück-Taste und gehen Sie zum Startbildschirm. Hinweis: Der Startbildschirm ist eine weitere Aktivität.
  4. Starten Sie Ihre Aktivität erneut -> Die statische Variable ist nicht null
  5. Beenden Sie Ihren Bewerbungsprozess über DDMS (Stopp-Schaltfläche im Gerätefenster).
  6. Starten Sie Ihre Aktivität neu -> die Statik hat den Wert Null.

Hoffentlich hilft das.

Samuh
quelle
1
Ich möchte wissen, warum ich meinen Feldwert im Anwendungsobjekt verliere, wenn er beim Starten einer neuen Aktivität nicht statisch ist. Ich deklariere beispielsweise die aktuelle Seite der Variablen im Anwendungsobjekt und ihr Wert kehrt beim Öffnen einer neuen Aktivität immer auf Null zurück
Mohammed Subhi Sheikh Quroush
wenn ich super.onRestoreInstanceState (savedInstanceState) aufrufe; Ich verliere meine Variable, auch wenn sie statisch ist. Was ist das Problem?
Mohammed Subhi Sheikh Quroush
1
Dies ist eine nette Erklärung (also keine -1), aber ein bisschen belanglos: Das OP fragte explizit nach "Situationen mit wenig Arbeitsspeicher" (der gleiche Grund, warum ich hier bin), wo meines Wissens die Os die VM töten könnten und Starten Sie es später mit denselben Parametern neu, und dieser Fall ( WENN es eine echte Sache ist) wird hier nicht behandelt ...
Rick77
1
@suitianshi Ich denke, wir können statische Instanzen in Application.onCreate initialisieren, denn selbst wenn unsere App in den Hintergrund tritt und der Prozess beendet wird, wird die Application-Klasse instanziiert und ruft die entsprechenden Lebenszyklusmethoden auf, sobald wir zu unserer App zurückkehren nochmal! Obwohl ich diesbezüglich eine Bestätigung benötige, frage ich mich, ob es ein Szenario geben könnte, in dem die in Application.onCreate initialisierte statische Instanz ihren Wert verliert.
Sarthak Mittal
1
Was mir hier fehlt, ist eine Erklärung für "1. Die Klasse wird entladen" - wann würde dies passieren? Würde JVM eine Klasse entladen, wenn der Speicher knapp wird?
stoefln
16

Nun, das Singleton-Muster basiert auch auf der Verwendung statischer Variablen, sodass Sie sich tatsächlich an derselben Position befinden würden. Während der statische Ansatz meistens funktioniert, kann es in einigen Fällen vorkommen, dass der Prozess Ihrer Aktivität abgebrochen wird und Sie die statischen Werte verlieren, wenn der Speicher voll ist und eine andere Aktivität im Vordergrund steht, bevor Ihre Anwendung zum nächsten Bildschirm wechselt. Android bietet jedoch einige Optionen zum Beibehalten oder Übertragen von Werten zwischen Status:

  • Mit einer Absicht können Sie Ihre Suchkriterien von Aktivität zu Aktivität weitergeben (ähnlich einer Web-http-Anfrage).
  • Mithilfe der Anwendungseinstellungen können Sie die Werte speichern und in der Aktivität abrufen, die sie benötigt
  • Mithilfe der SQLite-Datenbank können Sie sie in einer Tabelle speichern und später abrufen
  • Wenn Sie nur den Aktivitätsstatus speichern müssen, damit die Felder beim Neustart mit den zuvor ausgewählten Werten gefüllt werden, können Sie die Aktivitätsmethode onSaveInstanceState () implementieren. Beachten Sie, dass dies nicht für die Persistenz von Status zwischen Aktivitäten empfohlen wird.

Sie können einige Codebeispiele für die Verwendung von Einstellungen, Absichten und der SQLite-Datenbank erhalten, indem Sie den Aegis-Shield-Quellcodebaum in Google Code oder in anderen Open Source-Android-Anwendungen betrachten.

r1k0
quelle
6

Nach einigen Recherchen stellt sich heraus, dass die Verwendung von Application zum Speichern von Singletons keine so gute Idee ist, es sei denn, Sie sind bereit, sie neu zu erstellen:

Speichern Sie keine Daten im Anwendungsobjekt

also während die akzeptierte antwort ist technisch korrekt, es nicht alle Informationen zur Verfügung stellen.

Wie der obige Link andeutet, müssen Sie bereit sein, nach Null zu suchen und die Daten nach Möglichkeit neu zu erstellen, wenn Sie wirklich an diesem Modell festhalten möchten.

Rick77
quelle
3

@ r1k0 ist genau hier. Das Speichern von Daten in statischen Feldern einer Klasse bleibt nicht über alle Kills und Neustarts des Anwendungsprozesses hinweg bestehen. Android beendet routinemäßig Prozesse (Ausführen von Apps), wenn Speicher benötigt wird.

Laut Android-Dokument: Aktivitätsstatus und Auswurf aus dem Speicher ,

Das System beendet niemals eine Aktivität direkt. Stattdessen wird der Prozess abgebrochen, in dem die Aktivität ausgeführt wird, und nicht nur die Aktivität, sondern auch alles andere, was im Prozess ausgeführt wird, wird zerstört.

Mit den folgenden Methoden können Sie den Status von Grundelementen sowie serialisierbaren und parzellierbaren Objekten speichern und wiederherstellen. Diese werden während des normalen Aktivitätslebenszyklus automatisch aufgerufen.

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

Wenn Sie also eine Klasse haben, die nur statische Variablen enthält, können Sie den Status jedes Felds in onSaveInstanceState () speichern und in onRestoreInstanceState () wiederherstellen. Wenn Android den Prozess beendet, in dem Ihre App ausgeführt wird, wird der Status Ihrer Variablen gespeichert, und wenn Android Ihre App wiederherstellt, werden die Werte im Speicher im selben Status wie zuvor wiederhergestellt.

eric.mcgregor
quelle