Android gibt für seine Activities einen geordneten Lifecycle vor. Beim starten einer App wird für die "erste" Activity grundsätzlich onCreate(), dann onStart() und zuletzt noch onResume() ausgeführt. Während nur onCreate() überschrieben werden muss, können sämtliche anderen derartigen Methoden ausgelassen werden.
Nicht wirklich dokumentiert ist das Verhalten einer Activity bei Benutzerinteraktion. Ein Druck auf den back-Button schliesst die aktuelle Activity beispielsweise komplett durch Aufruf von onPause(), dann onStop() und schliesslich onDestroy(). Nicht ganz offensichtlich ist vielleicht, dass genau diese Methoden auch aufgerufen werden, wenn man das Handy um 90° dreht. Hier wird anschliessend die App komplett neu gestartet.
Mit folgender Activity kann man sich einfach anzeigen lassen, welche Methoden wann aufgerufen werden. Eine fertig kompilierte .apk für Android 1.5 und höher findet ihr bei den Links...
- Back-Button: onPause() -> onStop() -> onDestroy()
- Auflegen-Button: onPause(). Nach dem Entsperren des Screens wird onResume() ausgeführt
- Annehmen-Button: Bringt die Phone-App in den Vordergrund. Es wird onSaveInstanceState() -> onPause() -> onStop() ausgeführt. Nach dem Beenden der Phone-App wird onRestart() -> onStart() -> onResume() ausgeführt.
- Home-Button: onPause() -> onStop(). Beim "Neustart" der App wird onRestart() -> onStart() ausgeführt.
- Rotate: onSaveInstanceState() -> onPause() -> onStop() -> onDestroy() -> onCreate() -> onStart() -> onResumeInstanceState() -> onResume()
public class main extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show(); } @Override public void onSaveInstanceState(Bundle savedInstanceState) { Toast.makeText(this, "onSaveInstanceState", Toast.LENGTH_SHORT).show(); super.onSaveInstanceState(savedInstanceState); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { Toast.makeText(this, "onRestoreInstanceState", Toast.LENGTH_SHORT).show(); super.onRestoreInstanceState(savedInstanceState); } @Override public void onStart() { Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show(); super.onStart(); } @Override public void onPause() { Toast.makeText(this, "onPause", Toast.LENGTH_SHORT).show(); super.onPause(); } @Override public void onStop() { Toast.makeText(this, "onStop", Toast.LENGTH_SHORT).show(); super.onStop(); } @Override public void onResume() { Toast.makeText(this, "onResume", Toast.LENGTH_SHORT).show(); super.onResume(); } @Override public void onRestart() { Toast.makeText(this, "onRestart", Toast.LENGTH_SHORT).show(); super.onRestart(); } @Override public void onDestroy() { Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show(); super.onDestroy(); } }
Damit Daten beim Drehen des Screens nicht verloren gehen, speichert Android (fast) alle Daten einer App beim Beenden selbiger ab und stellt die Daten beim Neustart wieder her. Gesichert werden dabei generell alle Daten, die in mit einer ID versehen wurden. Alles andere muss man manuell sichern. Dafür legt man die Daten im Bundle savedInstanceState ab, welches der App bei onCreate() als Parameter übergeben wird. Hierfür sind die Funktionen onSaveInstanceState() und onRestoreInstanceState() gedacht. Hier kann man Daten aus dem Bundle auslesen bzw. in selbiges schreiben. Beim Beenden der App geht allerdings auch der InstanceState verloren. Will man Daten also über das Ableben einer App hinweg sichern, muss man diese in Dateien oder Datenbanken ablegen.
Das folgende Beispiel verdeutlicht, wie Daten im Bundle genutzt werden:
public class main extends Activity { int x; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); x++; savedInstanceState.putInt("x", x); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); x = 0; if (savedInstanceState != null) { if (savedInstanceState.containsKey("x")) { x = savedInstanceState.getInt("x"); } } Toast.makeText(main.this, "x: " + x, Toast.LENGTH_SHORT).show(); } }