Stand: 28.07.2020
Mobile Apps bestehen häufig aus verschiedenen Screens, zwischen denen man wechselt. Weiterhin ist es üblich, zwischen verschiedenen Apps zu wechseln, z.B. von einer Mail in der Mail-App zum Browser, um einen Link zu betrachten, und zurück, oder von einer Kamera-App zu einer Chat-App, um das Foto zu teilen.
7.1 Intents
Intents stellen Verbindungen zwischen den Activities her, sowohl zwischen Activities derselben App als auch zwischen Activities unterschiedlicher Apps. Wenn man von Activity A zu Activity B wechseln möchte, erzeugt man ein neues Intent-Objekt und teilt dieser mit, dass man Activity B (eine Klasse) aufrufen möchte. Anschließend übergibt man den Intent einer Android-Methode, die den Übergang regelt.
Wir haben es also bei einem einfachen Übergang zwischen zwei Activities mit diesen drei Objekten zu tun:
Warum soll so etwas vermeintlich Einfaches wie der Übergang von Activity A zu Activity B von einem Objekt geregelt werden? Reicht nicht ein einfacher Funktionsaufruf? Nein, denn Intent-Objekte können eine Reihe von Zusatzinformationen zum Übergang enthalten:
- es gibt verschiedene Typen von Übergängen
- es können Daten an die nächste Activity übergeben werden (bzw. eine aufgerufene Activity kann auch Daten zurückgeben)
- es ist möglich, dass keine konkrete nächste Activity, sondern Auswahlkriterien für eine nächste Activity übergeben werden
Man unterscheidet zwischen expliziten Intents und impliziten Intents. Explizite Intents benutzt man, um zu einer anderen Activity zu wechseln. Es handelt sich also um einen Übergang innerhalb der eigenen App.
7.2 Explizite Intents
Wir beginnen mit expliziten Intents.
7.2.1 Neue Activity
Dazu müssen wir zunächst eine neue Activity erstellen. In der Projektsicht (links) gehen wir auf java und dort auf unser Package und wählen per Rechtsklick: New > Activity > Empty Activity.
Nennen Sie die neue Activity "SecondActivity". Android Studio legt eine Java-Datei SecondActivity.java und eine Layout-Datei activity_second.xml an.
Wir stellen uns eine App vor, die zwei Screens hat (also zwei Activities). In der ersten Activity (MainActivity) haben wir eine Texteingabe und einen Button. Man kann eine beliebige "Nachricht" für die zweite Screen schreiben. Auf der zweiten Screen (= SecondActivity) möchten wir den Text zeigen, den der User auf der ersten Screen eingegeben hat.
7.2.2 Zweite Activity starten
Für den ersten Übergang erstellen wir ein Intent-Objekt, das sowohl die aktuelle Activity (this
) als auch die Ziel-Klasse (SecondActivity.class
) enthält:
Intent gotoSecond = new Intent(this, SecondActivity.class);
(Das this
kann problematisch sein - das sehen wir gleich...)
Bei dem Buttonklick "starten" wir den Intent mit der Methode startActivity
:
startActivity(gotoSecond);
Im Kontext sieht das so aus:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button next = (Button)findViewById(R.id.buttonNext);
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent gotoSecond = new Intent(MainActivity.this, SecondActivity.class);
startActivity(gotoSecond);
}
});
}
}
Wie Sie sehen, mussten wir diese Zeile leicht ändern:
Intent gotoSecond = new Intent(MainActivity.this, SecondActivity.class);
Grund ist, dass wir mit new View.OnClickListener()
eine Instanz einer neuen (anonymen) Klasse erstellen und ein this
auf genau dieses Objekt verweisen würde. Mit folgendem Ausdruck können wir Java in unserem Fall mitteilen, dass wir das "übergeordnete" Objekt meinen:
MainActivity.this
Zurück zum eigentlichen Thema: Auch wenn wir jetzt in der zweiten Activity sind, so ist die erste Activity immer noch "am Leben". Auf dem Endgerät können Sie jederzeit mit dem Back-Button zur ersten Activity zurückkehren. Mehr zum Thema "Back-Stack" werden Sie im Modul Lifecycle lernen.
7.2.3 Daten über Extras mitgeben
Wie geben wir der SecondActivity
den Text mit, den der User eingegeben hat? Wenn wir noch Daten an die zweite Screen mitgeben wollen, sind das sogenannte Extras.
Extras sind aufgebaut wie eine Tabelle: wir geben für jede Information (= String) einen Schlüssel an. Bei uns heißt der Schlüssel "secret". Wir verwenden die Methode putExtra
, um einem Intent eine Information hinzuzufügen.
Wenn wir also einen String foo
hätten, könnten wir ihn mit
gotoSecond.putExtra("secret", foo);
dem Intent hinzufügen.
Im Code kann das so aussehen. Wir holen hier den Text aus dem editierbaren Textfeld (editText). Wir brauchen das "final" bei dem Intent, damit wir innerhalb des Button-Handlers auf den Intent zugreifen können.
public class MainActivity extends AppCompatActivity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText)findViewById(R.id.editText);
Button next = (Button)findViewById(R.id.buttonNext);
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent gotoSecond = new Intent(this, SecondActivity.class);
gotoSecond.putExtra("secret", editText.getText().toString());
startActivity(gotoSecond);
}
});
}
}
Auf der zweiten Screen können wir uns die Extra-Infos holen mit
getIntent().getExtras().get("secret");
Alternativ können wir (kürzer) schreiben:
getIntent().getStringExtra("secret");
Im Code von SecondActivity
sieht das wie folgt aus:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
String message = getIntent().getStringExtra("secret");
((TextView)findViewById(R.id.textMessage)).setText(message);
}
7.2.4 Rückkehr mit finish
In SecondActivity rufen wir einfach die Methode finish()
auf, um wieder in die MainActivity zurückzukehren.
Im Code:
protected void onCreate(Bundle savedInstanceState) {
...
Button back = (Button)findViewById(R.id.buttonBack);
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
Bei der Rückkehr wird die Activity, die wir verlassen, unwiederbringlich zerstört.
Natürlich gibt es auch Situationen, wo Ihre zweite Activity eine dritte aufruft (und diese evtl. eine vierte). Sie sollten aber niemals in eine alte Activity über startActivity
zurückkehren. Warum das so ist, sehen Sie beim Thema "Back-Stack" im Modul Lifecycle.
7.3 Sub-Activity und Datenrückgabe [optional]
Es gibt Activities, die häufiger als "Dienst" verwendet werden, z.B. reine Eingabe-Screens für Namen, Adressen etc. Eine solche Activity kann also mit der Intention aufgerufen werden, dass ein Wert (z.B. Text) zurückgegeben wird. Dann spricht man auch von einer Sub-Activity.
7.3.1 Aufruf der Sub-Activity
Nehmen wir an, wir haben eine Activity A, die eine Sub-Activity B aufruft. Auch hier verwenden wir einen Intent, aber der Aufruf erfolgt mit startActivityForResult
.
Damit Activity A weiß, zu welchem Zweck B aufgerufen wurde, kann ein RequestCode (eine ganze Zahl) mitgegeben werden. Das ist insbesondere dann wichtig, wenn A mehrere Sub-Activities aufrufen kann, denn die Ergebnisse werden alle in einer einzigen Methoden aufgefangen.
Außerdem kann man dem eigenen Intent Extras mitgeben (s.o.). Damit kann man einer Eingabemaske mitgeben, was man genau abfragen will ("Name" oder "Telefon").
Nehmen wir an, Sie haben eine (Sub-)Activity FrageActivity
, die dem User eine Frage stellen kann und die Antwort zurückgibt.
Intent intent = (this, FrageActivity.class);
intent.putExtra("fragetext", "Warum ist die Banane krumm?");
startActivityForResult(intent, 0);
Den RequestCode setzen wir einfach auf 0.
7.3.2 In der Sub-Activity
In der Sub-Activity B wird z.B. eine Eingabemaske gezeigt und auf einen Input gewartet. Typischerweise hat man Buttons für "OK" und "Abbrechen". Sobald OK gedrückt wird, kann man in Activity A zurückspringen. Dazu
- erzeugt man ein neues Intent-Objekt und speichert mit
putExtra
die relevanten Infos (z.B. Texteingabe) - setzt mit
setResult
den Result-Code auf RESULT_OK und gibt das Intent-Objekt mit - ruft
finish
auf
Hinweis: Nicht den Result-Code mit dem Request-Code verwechseln! Der Result-Code besagt, ob der User abgebrochen oder bestätigt hat. Der Request-Code sagt der aufrufenden Activity, von welcher Sub-Activity das Ergebnis kommt.
In unserem Beispiel mit der FrageActivity nehmen wir an, dass wir eine EditText-Komponente in der Variablen editText halten. Sofern der User die Eingabe bestätigt, rufen wir dies auf:
Intent intent = new Intent();
intent.putExtra("antwort", editText.getText().toString());
setResult(RESULT_OK, intent);
finish();
Bei "Abbrechen" setzt man setResult
auf RESULT_CANCELED und ruft finish
auf.
Beachten Sie, dass die Sub-Activity nach Aufruf von finish komplett zerstört wird (siehe Modul Lifecycle).
7.3.3 Ergebnis auffangen
In Activity A wird nach Beendigung von Sub-Activity B die Methode onActivityResult
aufgerufen. Diese muss man also implementieren (d.h. überschreiben). Innerhalb der Methode kann man sich den ResultCode anschauen (ist entweder RESULT_OK oder RESULT_CANCELED) und den RequestCode (hat man selbst bestimmt). In dem mitgelieferten Intent-Objekt stehen die Extras, wo auch die Eingabe gespeichert wurde.
In unserem Beispiel wären wir z.B. wieder in MainActivity:
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == 0 && resultCode == RESULT_OK) {
String antwort = intent.getStringExtra("anwort", "KEINE ANTWORT");
...
}
}
Wie schon erwähnt, wird immer diese eine Methode aufgerufen, egal von welcher Sub-Activity wir zurückkehren (für den Fall, dass mehr als eine Sub-Activity von A aus aufgerufen werden kann). Der Request-Code dient in solchen Fällen dazu, die Ergebnisse korrekt zu behandeln. Hier haben wir der Sub-Activity lediglich eine 0 mitgegeben und bekommen diese auch zurück.
7.4 Zusammenfassung
Intents sind Objekte, die den Übergang von einer Activity A in eine andere Activity B erlauben. Ein einfacher Übergang besteht darin, dass man in Activity A einen neuen Intent für Activity B erzeugt und dann die Methode startActivity
aufruft. Will man aus Activity B wieder in Activity A zurückkehren, ruft man einfach finish()
auf.
Man kann in einem Intent Daten in Form einer Tabelle speichern, den sog. Extras. Diese Extras können in der Ziel-Activity B wieder abgerufen werden.
Man kann eine Activity B auch als reine "Datenbeschaffungs"-Activity mit Rückgabe sehen. Eine solche Activity könnte z.B. eine Usereingabe durchführen und das Resultat - ähnlich wie eine Funktion - zurückgeben. Dazu rufen wir B als Sub-Activity mit der Methode startActivityForResult
auf. Die aufrufende Activity muss das Resultat mit der Methode onActivityResult
auffangen.
7.5 Übung
Kontaktseite mit Edit-Activity
Schreiben Sie für eine Kontakte-App eine Sub-Activity, in der Sie eine Texteingabe machen können.
Ihre App besteht aus einer Seite mit Feldern für Name, Telefon und Mail:
Wird jetzt einer der drei Edit-Buttons betätigt, springt die App in eine Sub-Activity, in der die Texteingabe erfolgen kann. Beachten Sie, dass über dem Texteingabe-Feld (Klasse EditText, in der Design-Ansicht unter "Plain Text") noch steht, um welche Eingabe es sich handelt (Name, Telefon oder Mail):
Wenn auf OK geklickt wird, wird die Eingabe in das entsprechende Feld übernommen:
Hier nochmal schematisch der Ablauf: