MainActivity wird unerwartet neu aufgebaut und läuft parallel zur alten !

  • Hallo,


    Ich habe eine App geschrieben, die Daten aus der Location-Api periodisch in eine Textdatei schreibt. Sie registriert sich im System beim Listener (Location Manager), welcher eine Callback-Methode aufruft und die Daten übergibt. Diese werden dann in eine Textdatei geschrieben.
    Die App läuft soweit perfekt und zu 95% stabil. Es kommt jedoch manchmal vor, dass sich scheinbar die MainActivity neu erstellt (was ich an der Oberfläche sehen kann, da sich dann die UI wie nach einem Erststart der App neu aufbaut) allerdings die alte Activity im Hintergrund weiterläuft (was ich wiederum daran erkennen kann, dass die Datei weiter aufgezeichnet wird! D.h. es werden weiterhin neue Daten in die Datei geschrieben.)


    Problem 1: Die UI sieht aus, als ob nicht aufgezeichnet werden würde, weil sie gerade erst "neu gestartet" ist. In Wirklichkeit findet aber eine Aufzeichnung statt. Die App befindet sich in einem inkonsistenen Zustand.
    Problem 2: Wenn man in der neu aufgebauten UI (bzw. Activity) auf "Start" drückt, dann wird ein neuer Listener registriert und da die alte Activity mit dem alten Listener noch läuft, findet eine doppelte Aufzeichnung statt! D.h., es werden Daten doppelt in die Textdatei geschrieben und das auch noch ziemlich asynchron, da ziemlich oft geflusht wird -> Datei wird völlig unbrauchbar / zerschrieben.
    Screen-Rotation ist übrigens aus (immer Portrait).
    mir scheint es, als ob dieser Activity-Neuaufbau besonders häufig bei meinem Samsung S8 auftritt. Ich kann allerdings nicht sagen, wie und wann das passiert. Ich kann es leider nicht bewusst erzwingen. Mir scheint es, als ob dies manchmal passiert, wenn die App in den Hintergrund geht und dann längere Zeit dort bleibt bzw. das Gerät in Schlafmodus gegangen ist.


    Fragen:
    1.) Unter welchen Bedingungen tritt dies auf (also dass die MainAcitivity+UI neu aufgebaut wird und die alte MainActivity weiterläuft bzw. die darin enthaltene Callback-Funktion immer weiter aufgerufen wird).
    2.) Wie könnte ich elegant und einfach Problem 1 und 2 lösen? Ich meine Problem 1 evtl. mit static Variablen lösen zu können, sicher bin ich mir aber nicht.


    Danke

  • Hi wie machst du das mit den Speichern? Du willst also auch Daten speichen auch wenn die App nicht im Vordergund ist.
    Für sowas würde ich einen Service schreiben der die Daten abfragt und speichert. Unabhängig von der Acktivity. Vor dem Start des Service solte man prüfen ob er schon läuft. Und über die Activity solte er auch beendet werden Können.

  • Hi! Danke für deine Antwort.


    Ich benutze die Android Location Services, etwa so wie in diesem Post:


    https://stackoverflow.com/ques…statuschanged-not-working


    Ich registriere beim Listener die Callbackfunktion die vom System regelmäßig aufgerufen wird. Dort drinnen habe ich den FileWriter der die Datei schreibt. Damit läuft das ganze auch in einem eigenen Thread und meiner Meinung nach auch unabhängig von meiner Activity. Deswegen meine ich, dass ich quasi bereits in diesen Service alles ausgelagert habe und nichts eigenenes schreiben soll.
    Die Callbackfunktion schreibt nur, wenn logging_flag = true ist. Dieser ist in der MainActivity deklariert und wird dort auch über die UI geändert. Klappt alles wunderbar. Nur wenn dieser mysteriöse Activity-Neustart bzw. Neuaufbau der UI passiert, ist logging_flag false (da onCreate() ihn auf false setzt) und die App quasi im Neuzustand aber der Service läuft weiter, sprich die Callbackfunktionen werden immer noch aufgerufen und das Logging findet weiterhin statt, was nur sein kann, wenn logging_flag true ist. Deshalb vermute ich, dass die logging_flag nun irgendwie 2 mal existieren muss, weil vielleicht eine neue Instanz von MainActivity erzeugt wurde.


    Ich würde gerne verstehen, was hier vor sich geht.

  • hi wie so hast du den FileWriter in der Mainactivity ? kannst du nicht in dem Service die daten Schreiben?


    Das deine Mainactivity neustartet ist nicht sehr verwunderlich den das BS kilt Prozesse selber wenn es Speicher z.b. für andere Apps braucht. Wenn dann dein Service wieder Daten schreiben will startet das BS deine App wieder.


    Du solltest in der onCreate() Prüfen ob den Service activ ist und dann dann dein flag auf true setzen.


    besser ist es aber die Daten im Service zu Speichern und nicht in der App mit Callback.

  • Also der FileWriter schreibt in der Callbackfunktion in der MainActivity und das funktioniert ganz sehr gut. der Google-Service ruft die Callbackfunktion immer auf, solange die App nicht beendet wird und egal ob sie durch den Home-Button in den Hintergrund geschickt wird, die Activity durch den Back-Button destroyed wird oder der Screen schwarz wird.


    Muss ich da wirklich noch groß was ändern zu dem wie es so ist? Ich muss ja theoretisch nur dafür sorgen, dass nach dem destroy und Neustart der App die Buttons wieder den Zustand erhalten und verhindern, dass der Listener ein zweites mal registriert wird, damit keine doppelte Aufzeichnung auftritt.


    Aber was genau meinst du mit eigenem Service bauen eigentlich? Könntest du mir einen Link schicken wo das erklärt wird? Hört sich für mich richtig an und würde ich gerne lernen, um das bei der nächsten App von Anfang an richtig zu machen.

  • Hallo bin mir nicht sicher ob die Activity bei betätigen des Back Button wirglich destroyed. Meine die geht in Stopp. Sonst könnte die Callback Methode auch nicht mehr ausgeführt werden. Wenn aber die Ressourcen knapp werden beendet android den Prozess. Und wenn ein Ergebnis Eintritt zb das Schreiben der Daten wird sie komplett vom neuen gestartet. Was bei dir auch der Fall sein dürfte. Werde es mal testen in welchen Status die App nach drücken des back Button geht.

  • du hast wahrscheinlich recht, dass beim Back-Button onStopp() und nicht onDestroy() ausgelöst wird:


    https://developer.android.com/…s/activity-lifecycle.html


    sicher ist nämlich, dass danach onCreate() ausgeführt wurde.


    Ich war von onDestroy() ausgegangen, weil für mich fest stand, dass die logging_flag - Variable zwei mal existiert hat. D.h., die alte wurde destroyed und eine neue erstellt aber das destroyen wurde nicht ganz abgeschlossen, weil der alte Service noch die Callbacks regelmäßig gerufen hat... oder so.


    Wovon hängt es eigentlich ab, ob nach onStop() onRestart() oder onCreate() ausgeführt wird? (siehe link). Kann es vielleicht sein, dass automatisch onCreate() ausgeführt wird, wenn man onResume() nicht überschrieben hat?

  • Hallo ich habe es gerade getestet es wird onDestry ausgeführt. Habe mich gerirrt. Was nicht beendet wird ist der Prozess.
    Der wird entweder durch finish() oder vom System gekillt.


    Die OnCreate wird nach einen Destrty immer ausgefürt.
    meistens auch nach Stopp. Nur wenn die App im hindergrund war und du die App wieder in den vodergrung holst wird onCreate nicht ausgefürt.



    Schaue dir den Activity livecycle nochmal an.
    hier ein guter Link dazu.


    http://www.programmierenlernen…y-und-fragment-lifecycle/


    Wovon hängt es eigentlich ab, ob nach onStop() onRestart() oder onCreate() ausgeführt wird? (siehe link). Kann es vielleicht sein, dass automatisch onCreate() ausgeführt wird, wenn man onResume() nicht überschrieben hat?



    Mit dem überschreiben hat das nichts zu tun.


    onRestart: z.B. wenn du dein Home Bildschirm aufrufst und dann wieder zurück zur App gehst.



    onCreate : wenn die App im Hindergrund ist und das System aus speichermangel den Process beendet. oder du die Abb beendest egal ob mit BackButton oder mit finish also onDestry durchlaufen wird.



    Die Methoden werden auch durchlaufen auch wenn sie nicht @Override werden.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!