Anwendungen bestehen in Android aus Activities. Darunter
versteht man Klassen, welche eine Komponente der Anwendung
darstellen und mit einer Benutzerschnittstelle ausgestattet sind.
Eine Anwendung kann aus mehreren Activities bestehen. Activities
können andere Activites starten. Die Main-Activity beschreibt die
Activity, die dem Benutzer beim Start der Anwendung angezeigt wird.
Diese könnte ein Menu enthalten. Wird ein Menueintrag ausgewählt,
kann zum Beispiel eine neue Activity gestartet werden.
Lebenszyklus einer Activity
Die Android Plattform ist so konzipiert, dass immer nur eine
Activity zu einem bestimmten Zeitpunkt aktiv sein kann. Aus diesem
Grund gibt es einen festgelegten Lebenszyklus für Activities. Die
Plattform ruft je nach Stand innerhalb des Zyklus bestimmte
Methoden der Activity auf. Diese Methoden sind in der Oberklasse
android.app.Activity
implementiert. Um auf den Lebenszyklus Einfluss zu nehmen, können
diese Methoden in der eigenen Activity-Klasse überschrieben werden.
Die folgende Abbildung stellt den gesamten Lebenszyklus dar. In den
grauen Rechtecken befinden sich die angesprochenen überschreibbaren
Methoden.
Um eine Activity zu erstellen, muss wie bereits angesprochen eine
Subklasse von
android.app.Activity
erstellt werden. In der Subklasse muss mindestens die Methode
onCreate()
implementiert werden. Im einfachsten Fall wird das XML-Layout der
Benutzeroberfläche in dieser Methode geladen, welches dann mittels
der Methode
setContentView()
aktiviert wird. Andere wichtige Callback-Funktionen werden in den
Abschnitten über Zustände von Activities behandelt, da sie in
diesem Zusammenhang am häufigsten benötigt werden. Jede
Android-Anwendung besitzt auch ein Manifest. In dieser XML-Datei
muss die Activity eingetragen werden:
<activity android:name=".MyActivity" />
Intents und Starten einer Activity
Mit Intents beschreibt man Absichten, welche einer zu
startenden Activity mitgeteilt werden. Anders ausgedrückt, will man
eine Activity starten, so muss man ihr den Grund dafür mitteilen.
Mit welchen Intents eine Activity umgehen kann, wird in der
Manifest-Datei festgelegt. Für die Haupt-Activity ist hierfür
bereits ein Eintrag vorhanden:
Das eigentliche Starten einer Activity geschieht mit der Methode
startActivity()
, welche als Parameter ein Intent erhält. Ein Intent wird mit der
Klasse
Intent
erstellt. Ein Intent muss die zu startende Activity beschreiben.
Daher kann als Parameter für den Konstruktor eine Activity-Klasse
angegeben werden oder eine Aktion, die durchgeführt werden soll:
Intent intent = new Intent(this, MyOtherActivity.class);
startActivity(intent);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
Im zweiten Code-Beispiel wurden dem Intent noch zusätzliche Daten
mit der Methode
putExtra()
hinzugefügt. Auf diese Art ist es möglich, zwischen Activities
Daten auszutauschen.
Es gibt noch eine weitere Art, Activites zu starten. Möchte man von
einer Activity ein Ergebnis erhalten, so muss man die Methode
startActivityForResult()
verwenden. Zusätzlich muss die Methode
onActivityResult()
überschrieben werden, in welcher man auf das Ergebnis reagieren
kann.
Zustand einer Activity
Eine Besonderheit der Android-Plattform ist, dass eine
Activity zu jeder Zeit unterbrochen werden kann. Dies kann zum
Beispiel passieren, wenn eine andere Activity in den Vordergrund
rückt, wie es unter Anderem bei einem eingehenden Anruf der Fall
ist. Dabei kann es je nach Situation vorkommen, dass die Activity
vom System zerstört wird. Nachdem die Activity, die sich in den
Vordergrund gedrängt hat, wieder beendet wurde, erwartet der
Benutzer in der Regel, dass er die vorherige Activity im alten
Zustand vorfindet. Dieser Umstand macht es nötig, den Zustand einer
Activity bei Bedarf zu speichern und wieder herzustellen.
View-bezogene Daten müssen nicht selbst behandelt werden, da dies
bereits von der Android-Plattform getan wird.
Speicherung des Zustands
Die Speicherung des Zustandes erfolgt in der Methode
onSaveInstanceState()
. Diese wird vom System automatisch aufgerufen, wenn es nötig ist.
Der Methode
onSaveInstanceState()
wird ein Objekt vom Typ
Bundle
übergeben, in welchem Daten in Schlüssel-Wert-Paaren abgelegt
werden können.
Wiederherstellung des Zustands
Die Methode
onCreate()
erhält als Parameter ein
Bundle
. Wurde vorher die Methode
onSaveInstanceState()
aufgerufen und Werte gesichert, so können diese nun beim erneuten
Erstellen der Activity zur Wiederherstellung des Zustandes genutzt
werden. Wurde
onSaveInstanceState()
nicht aufgerufen, so ist der
Bundle
-Parameter
null
.
Beispiel
Um die Fakten aus den vorherigen Abschnitten zu erproben,
wird nun eine kleine Beispielanwendung erstellt. Diese soll eine
kurze Nachricht ausgeben, wann immer eine Callback-Methode vom
System aufgerufen wird. Wird die Orientierung der App geändert, so
wird diese zerstört und neu erstellt. Daher ist das Speichern und
Wiederherstellen des Zustands nötig.
Als erstes wird in Eclipse ein neues Projekt mit einer Activity
angelegt. In der automatisch angelegten Activity werden nun als
erstes die Callbackmethoden aus obiger
Abbildung sowie die Methode
onSaveInstanceState()
implementiert. Der Code sieht nun wie folgt aus:
Um das Speichern des Anwendungszustandes zu testen, wird ein
Textfeld zur View hinzugefügt. Dies geschieht über den grafischen
Editor.
Der Inhalt des Textfeldes soll persistiert werden. Zuerst wird
etwas Text in das Textfeld eingegeben. Dreht man nun das Endgerät,
so sollte die Activity zerstört und neu erstellt werden. Dies
erkennt man am Aufruf der Callbackmethoden
onDestroy()
und
onCreate()
. Der eingegebene Text sollte nun wieder im Textfeld angezeigt
werden.
Nun werden wir eigene Daten beim Aufruf der Methode
onSaveInstanceState()
speichern:
Anschließend ändern wir die Methode
onCreate()
so ab, dass die gespeicherten Daten - falls vorhanden - ausgegeben
werden.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (savedInstanceState == null) {
Toast.makeText(this, "onCreate (nothing to restore)", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, savedInstanceState.getString("data") + " restored",
Toast.LENGTH_SHORT).show();
}
}
Beim ersten Start der Anwendung sollten keine gespeicherten Daten
vorliegen. Daher wird die erste Meldung ausgegeben. Dreht man nun
das Endgerät, so werden wieder die Lifecycle-Callbacks aufgerufen,
auch
onCreate()
. Diesmal wird die zweite Meldung mit den gespeicherten Daten
angezeigt