Warum warten die Lifecycle-Methoden nicht?

T

txbarth

Ambitioniertes Mitglied
0
Hallo,

ich habe feststellen müssen, dass die Folgemethoden von onCreate nicht warten, bis alles ausgeführt worden ist. Ich habe in meiner onCreate-Methode der MainActivity weitere Methodenaufrufe, um z.B. einen Service zu starten und zu binden. Dabei wird auch eine Verbindung zu einer Server-App hergestellt, aber onStart und onResume werden bereits aufgerufen, obwohl die in onCreate-Methoden noch nicht fertig sind. Selbst ein Sleep in onCreate wird "übergangen". Muss das so sein?
 
Service Lifecycle und Activity Lifecycle sind unabhängig voneinander. Normalerweise sollte man das auch nicht in der selben Klasse implementieren.
 
Hm?

Sowas wird doch in der onCreate-Methode aufgerufen.

zu onCreate aus Doku:
"Called when the activity is first created. This is where you should do all of your normal static set up — create views, bind data to lists, and so on..."

Code:
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Report.print("MainActivity.onCreate()");

        ActivityRegister.register(this);
        Data.addNewObserver(this);

        startNotifyService();
        bindNotifyService();
}

private void startNotifyService() {
    Report.print("MainActivity.startNotifyService()");

    Intent intent = new Intent(this, NotifyService.class);
    startService(intent);
}

private void bindNotifyService() {
    Report.print("MainActivity.bindNotifyService()");
    Context context = getApplicationContext();
    bindService(new Intent(context, NotifyService.class), serviceConnection, Context.BIND_AUTO_CREATE);
}

Aber wenn ich dann im Logging sehe

06-28 07:33:28.067 1586-1586/... V/HALLO: MainActivity.onCreate()
06-28 07:33:28.067 1586-1586/... V/HALLO: MainActivity.startNotifyService()
06-28 07:33:28.067 1586-1586/... V/HALLO: MainActivity.bindNotifyService()
06-28 07:33:28.067 1586-1586/... V/HALLO: MainActivity.onStart()
06-28 07:33:28.067 1586-1586/... V/HALLO: MainActivity.onResume()
06-28 07:33:28.185 1586-1586/... V/HALLO: NotifyService.onCreate()
06-28 07:33:28.185 1586-1586/... V/HALLO: NotifyService.onStartCommand() Received start id 1: Intent { cmp=....NotifyService }
06-28 07:33:28.716 1586-1586/... V/HALLO: MainActivity serviceConnection.onServiceConnected has been established
06-28 07:33:30.196 1586-1601/... V/HALLO: SessionWorker.run() Verbindung zum Server herstellen
06-28 07:33:30.226 1586-1601/... V/HALLO: ServerConnector.connect() Verbindung hergestellt mit HOST ...


also MainActivity.onStart() und MainActivity.onResume() noch vor dem übrigen, obwohl onCreate die Methoden aufruft, dann ist das irgendwie gegen die Natur einer natürlichen Programmierung.
 
Also ich finde das völlig normal. (Deine Ansicht von "natürlicher Programmierung" ist offenbar nicht die meine ;-)
Stell dir den Service-Klüngel wie einen Webserver auf deinem Rechner vor.
Warum sollte dessen Start irgendwie davon abhängen, wann dein Browser (die Activity) auf dem Rechner sein Fenster öffnet?

Aber ich gebe zu, diese ganzen Nebenläufigkeiten machen den Umgang nicht gerade leicht - vor allem, wenn man ohne Global State auskommen soll/will.
 
  • Danke
Reaktionen: Kiwi++Soft
Natürlich ist ein Web-Browser nicht abhängig vom Server, aber ein Browser-Tab hängt von den Daten ab, die der Server liefern soll. Und wenn da nichts kommt, gibt es irgendwann ein Timeout. Meine MainActivity ist, um bei dem Beispiel zu bleiben, wie ein Browser-Tab, das Daten bereits anzeigen könnte, wenn die Reihenfolge der Methodenaufrufe eingehalten würde. Denn onResume enthält bei mir eine Methode, die Daten aus dem Datenmodell abfragt. So aber habe ich erst einmal 0-Werte, bis diese nach Eintreffen der Daten überschrieben werden.
 
Lifecycle: Activity | Android Developers

Dein Bild ist falsch. Der Lifecycle wird vom System gesteuert. Ohne den Lifecycle kann das System auf Ereignisse, wie ein Telefonanruf oder ein leerer Akku, nicht angemessen reagieren. Für den User ist ein funktionierendes Smartphone viel wichtiger, als eine kleine App, die ihren Content nicht vernünftig lädt.
Statt dessen solltest du Dir überlegen, ob den Service wirklich binden muss. Es geht auch mit einer lockeren Koppelung. Für was gibt es den sonst BroadcastReceiver. Klassen zu binden, ist fast immer schlechter Stil. Meist zeugt es von Designfehlern im Programmcode, wenn es die einzige Möglichkeit ist.
 
  • Danke
Reaktionen: Kiwi++Soft
@txbarth: Erstmal nix anzeigen ist genau das, was ein Browsertab macht, wenn die neue Seite noch nicht da ist. Blocken bis zum Timeout wäre extrem schlechter Stil.

Im übrigen: Ein Download per Service zu realisieren, ist nicht unbedingt die richtige Lösung (but YMMV), da tut es meist ein AsyncTask, da hast du dann auch die passenden Callbacks für ProgressDialoge.
 

Ähnliche Themen

S
Antworten
3
Aufrufe
640
swa00
swa00
OnkelLon
Antworten
7
Aufrufe
1.232
thomaspan
thomaspan
M
  • maksimilian
Antworten
5
Aufrufe
865
maksimilian
M
Zurück
Oben Unten