Android tötet keine Aktivitäten vom Stapel, wenn der Arbeitsspeicher niedrig ist

8

Wir haben eine Anwendung entwickelt, die über ein Dropdown-Dashboard verfügt, mit dem die Benutzer durch die App navigieren können. Die Navigation ist nicht sehr standardisiert, da auf dieses Menü von fast jeder Aktivität aus zugegriffen werden kann. Nachdem Sie eine Weile mit dem Öffnen von Aktivitäten über das Menü gespielt haben, beginnt der Stapel zu wachsen und zu wachsen.

Alle diese Aktivitäten enthalten Listenansichten mit mehreren Bildansichten, die jeweils etwa 3 MB benötigen. Wenn der Benutzer genug spielt und mehr als 25 Aktivitäten auf dem Stapel erstellt, geschieht Folgendes:

  1. Nicht genügend Speicherfehler wird ausgegeben (Heap wird erhöht, bis kein Heap mehr vorhanden ist).
  2. Ein Dialog wird aufgrund der Ausnahme angezeigt (Leider wurde% activity% gestoppt.)
  3. Die Aktivität, bei der der outofmemerror ausgelöst wurde, ist beendet.
  4. Alle Aktivitäten im Stapel sind beendet, aber der Verlauf wird beibehalten, so dass Backups möglich sind und jede Aktivität automatisch vom Betriebssystem neu erstellt wird.

Ich habe erwartet, dass das System die ältesten Aktivitäten im Stack automatisch löscht, BEVOR der OutOfMemoryError geworfen wurde ...

Um sicher zu gehen, dass das Betriebssystem keine alten Aktivitäten löscht, habe ich eine Test-App erstellt, die jedes Mal 1 MB zuweist. Raten Sie was: Das Verhalten ist das gleiche und outofmemerror wird geworfen:

Die Frage ist: Wie können wir dem Android-Betriebssystem mitteilen, dass es bei Bedarf Aktivitäten und Ressourcen freigeben darf, damit wir nicht "Leider wurde Ihre Aktivität gestoppt" erhalten? Dialog?

Nachweis des Konzepts

%Vor%

    
Gaspar de Elias 23.07.2012, 16:26
quelle

4 Antworten

13
  

Ich habe erwartet, dass das System die ältesten Aktivitäten im Stack automatisch beendet, BEVOR der OutOfMemoryError ausgelöst wurde

Android macht das nicht. Android beendet Prozesse, um Systemspeicher für andere Prozesse freizugeben. In ähnlicher Weise wird es nicht mit der Intra-App-Speichernutzung in Verbindung gebracht.

  

Wie können wir dem Android-Betriebssystem mitteilen, dass es bei Bedarf Aktivitäten und Ressourcen freigeben darf, damit wir nicht "Leider wurde Ihre Aktivität gestoppt" erhalten? Dialog?

Sie können nicht.

Stattdessen müssen Sie Ihre Anwendung so entwerfen, dass weniger Aktivitäten verwendet werden oder weniger Ressourcen pro Aktivität verwendet werden. Sie können beispielsweise vorhandene Aktivitätsinstanzen über FLAG_ACTIVITY_REORDER_TO_FRONT "recyceln" oder ( wie Herr Tornquist darauf hingewiesen hat), können Sie finish() activities manuell selbst durchführen.

  

Nachdem Sie eine Weile mit dem Öffnen von Aktivitäten über das Menü gespielt haben, beginnt der Stapel zu wachsen und zu wachsen.

Sie sollten wahrscheinlich FLAG_ACTIVITY_REORDER_TO_FRONT für diese Menüelemente verwenden, damit Sie die vorhandene Aktivität in der Aufgabe weiterleiten und nicht jedes Mal neue erstellen.

    
CommonsWare 23.07.2012, 16:45
quelle
1

Wenn Sie finish() aufrufen, wenn Sie die neue Aktivität starten, wird die Zuweisung aufgehoben, die Sie verlassen. Dies verhindert, dass Sie mit der Zurück-Taste darauf zugreifen können, aber es sollte den Speicher im Speicher halten.

    
Nathan Tornquist 23.07.2012 16:31
quelle
0

Ich hatte auch den Eindruck, dass das System alte Aktivitäten zum Freigeben von Speicher beenden wird, laut Android-Entwicklerführer:

"Wenn das System eine Ihrer Aktivitäten stoppt (z. B. wenn eine neue Aktivität beginnt oder die Aufgabe in den Hintergrund rückt), kann das System diese Aktivität vollständig zerstören, wenn es Systemspeicher wiederherstellen muss. In diesem Fall werden Informationen über Der Aktivitätsstatus ist verloren. Wenn dies geschieht, weiß das System weiterhin, dass die Aktivität einen Platz im Backstack hat, aber wenn die Aktivität an den Anfang des Stacks gebracht wird, muss das System sie neu erstellen (anstatt sie fortzusetzen) Um den Verlust der Arbeit des Benutzers zu vermeiden, sollten Sie ihn proaktiv beibehalten, indem Sie die onSaveInstanceState () - Callback-Methoden in Ihrer Aktivität implementieren. "

siehe Link: Android-Aktivitäten

    
ebs 05.10.2012 10:53
quelle
0

Verwenden Sie das Intent Flag FLAG_ACTIVITY_REORDER_TO_FRONT

%Vor%

Das bringt ActivityA einfach an die Spitze des Stapels und lässt B und C dort, wo sie sind, was ich glaube, was Sie wollen. Dann können Sie natürlich finish () auf D aufrufen, wenn Sie es vom Stapel entfernen möchten.

    
GAGAN BHATIA 17.07.2017 10:59
quelle