# Android System löscht benötigte Teile der App aus Speicher



## Dooku (9. Mrz 2014)

Hi,
ich hab vor kurzem eine Android-App released. Aufgrund steigender Userzahl kommt es allerdings immer häufiger zu Abstürzen der selben Art. Es handelt sich dabei um eine NullPointerException in onCreate(), bzw. onResume()-Methoden verschiedener Activities. Grund für die Exception ist, dass eine Membervariable der Klasse "AssetLoader" nicht (mehr) existiert. AssetLoader sieht etwa wie folgt aus:

```
public class AssetLoader{
    public static ClassA a;
    public static ClassB b;
    public static ClassC c;
    ...
}
```
Die einzelnen Membervariablen halten einen großen Teil der von meiner App benötigten Resourcen. 
z.B hier kommt es dann zum Fehler:

```
@Override
protected void onResume(){
   AssetLoader.a.doSth(); //Führt zur Exception
...}
```

Es gibt eigentlich nur ein Szenario in dem AssetLoader.a == null wäre:
Der User verlässt die App ohne sie zu schließen. Während er mit etwas anderem beschäftigt ist zerstört das System die Instanzen a,b,c,... , sowie die derzeitige Activity. Navigiert der User jetzt zurück wird wohl die letzte Activity (des wohl noch existierenden Tasks) wieder neu gestartet, allerdings sind alte Instanzen (wie die "Memberobjekte" von AssetLoader) nicht mehr vorhanden. Das ist jetzt natürlich spekuliert, vllt weis da ja jemand besser bescheid? Wie kann man sich denn hier Abhilfe verschaffen?

MfG


----------



## ruerob (10. Mrz 2014)

Hallo Dooku,

du könntest alle Eigenschaften von AssetLoader zwischenspeichern entweder in eine TextDatei oder in SharedPreferences, wenn deine App geschlossen oder in den Ruhezustand versetzt wird. Wenn sie dann wieder gestartet wird, lädst du von dort den letzten Stand wieder nach und hast deine Klassen wieder.

So mach ich das jedenfalls immer.

Sei freundlich gegrüßt,

ruerob.


----------



## Dooku (10. Mrz 2014)

Leider ist das nicht so ohne weiteres möglich, da es sich um eine Multiplayerspiel handelt. Dh, es kann nicht einfach an den alten Stand "angeknüpft" werden. Wenn also erstmal eine Lücke besteht (im Normalfall würde die App nämlich auch noch im Hintergrund weiter Arbeit verrichten) ist die App nicht mehr funktionstüchtig. 

Für die Userfreundlichkeit ist es also meines Erachtens besser die App ganz zu schließen anstatt die Activities und andere Objekte (die statischen Member von AssetLoader) zu zerstören/zerstören zu lassen (um sie dann später "wiederherzustellen") . Der User würde die App dann bei Bedarf einfach erneut von Anfang an starten. 

Eine mögliche Methode die mir da in den Sinn käme wäre direkt zu Anfang in onCreate killProcess() aufzurufen (davor evtl noch eine Mitteilung an den User). Allerdings müsste man hier irgendwie differenzieren können ob onCreate() "normal" oder zur Wiederherstellung aufgerufen wurde...?
Besser wäre es natürlich den Prozess direkt abzuschießen, wenn Android die Activities zerstören will. Hier fehlt mir jedoch jegliche Idee für einen Ansatz (womöglich könnte man hier etwas in Application implementieren??). 

Hat jemand Ideen oder ist wirklich generell davon abzuraten hier den "vorhergesehenen Weg" zu verlassen?

Grüße


----------



## dzim (10. Mrz 2014)

Dann solltest du die Arbeit vielleicht in einen Service - idealerweise, damit es *wirklich* im Background weiter geht, einen IntentService - implementieren. Die UI musst du dann mit Broadcasts aktualisieren (also logischweise einen BroadcasReceiver implementieren) oder aber deine UI checkt, ob ein Service läuft, meldet sich dort an (via Messanger z.B.). Bedenke, dass es aber eine saubere und dem Nutzer klar verständliche Art geben muss, die App auch wirklich zu beenden. Nur über den Tasker "wegschieben" ist IMHO nicht gerade die feine Art. Da muss ein Button sein, der sagt: "STOPPE DIE APP, SONST BATTERIE LEER" ;-)
Oder wenn er back drückt, dass er hingewiesen wird, dass die App noch aktiv ist, ob er das möchte. Irgendwie so was.


----------

