Stand: 21.07.2018

Wir programmieren eine erste App und lernen Grundbegriffe kennen, die wir später ausbauen.

Die einfachste mögliche App besteht aus einer Activity und einem View. In der View definieren wir die grafische Oberfläche (die Screen), d.h. welche Komponenten (Buttons, Texte etc.) sichtbar sind. In der Activity, die aus Java-Code besteht, legen wir die Funktionalität fest, also z.B. welche Aktionen ausgeführt werden, wenn man auf einen Button drückt.

Android Studio

Zunächst legen wir ein erstes Projekt an und erläutern anhand dessen die Konzepte Activity und View. Am Ende soll unser erstes Projekt wie folgt aussehen:

Erste App

2.1 Projekt anlegen

Mit File > New > New Project... legen wir ein neues Projekt an.

Dazu geben Sie einen Namen, den Ablageort (Verzeichnis, i.d.R. gleicher Name wie das Projekt) und die "Domäne" an. Die Domäne wird dann rückwärts gelesen als Paketname benutzt, also z.B. wird aus Domäne hsa.de das Paket de.hsa:

Projekt anlegen

Anschließend legen Sie die Minimalvoraussetzungen für Ihr Projekt fest. Android liegt ja in vielen Versionen vor. Je höher sind gehen, umso mehr Features können Sie nutzen, dafür können aber Android-Geräte mit älteren Versionen Ihre App nicht abspielen.

Projekt anlegen

Geben Sie dann Empty Activity an. Bei den anderen Optionen wird zusätzlicher Code erzeugt, der zu Beginn verwirrend sein kann:

Projekt anlegen

Hier lassen Sie einfach die Defaultwerte drin:

Projekt anlegen

2.1.1 Projektansicht

Jetzt öffnet sich die "normale" Projektansicht mit einem großen Code-Bereich rechts, der natürlich noch leer ist.

Android-Studio

Falls Sie links kein Teilfenster haben, klicken Sie auf project am linken Rand des Gesamtfensters.

Android-Studio Projektsicht

Im linken Teilfenster sehen Sie Ihr Projekt und die entsprechenden Verzeichnisse, hier haben wir einige ausgeklappt:

Projektsicht

Die Projektsicht ist eine vereinfachte Sicht auf Ihre Verzeichnisse. Android Studio will Ihnen so das navigieren erleichtern. Im nächsten Abschnitt sehen wir, wie das auf der Festplatte aussieht.

2.1.2 Auf der Festplatte

Wo befinden sich die Verzeichnisse auf der Festplatte? Wenn Sie in Ihr Projektverzeichnis gehen, sehen Sie:

Projektverzeichnis

Sie sehen also, dass die Projektsicht in Android Studio vereinfacht ist. Auf der Festplatte müssen Sie zuerst in app/src/main hineingehen.

Sinnvoll ist noch ein Blick in das Verzeichnis app/src/main/res:

Ressourcenverzeichnis

Hier liegen die sogenannten Ressourcen (engl. resources), dazu gehören u.a. auch Bilder und Videos, die Sie hier deponieren - Bilder z.B. unter drawable.

2.2 Activity: Der Einstiegspunkt

Eine Android-App ist im Grunde eine Ansammlung von Activities. Man kann sich eine Activity als eine Bildschirmseite auf dem Smartphone vorstellen. Clickt oder wischt man zu einer anderen Seite, befindet man sich in der nächsten Activity.

Öffnen Sie jetzt den Code von MainActivity im Verzeichnis java (und dem von Ihnen fest gelegten Paket). Sie sehen jetzt Java-Code und insbesondere die Methode onCreate(). Das ist Ihr Einstiegspunkt!

package de.hsa.myapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // DIESE ZWEI ZEILEN NICHT ÄNDERN!

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // AB HIER EIGENER CODE
    }
}

Wie Sie sehen, ist eine Activity eine Java-Klasse, genauer gesagt eine Unterklasse der vorgegebenen Android-Klasse Activity bzw. AppCompatActivity (steht für app compatibility). Diese Activity ist der Einstiegspunkt in die App. Im Gegensatz zu einem traditionellem Java-Programm gibt es keine statische Methode main(). Stattdessen wird beim Start der App die Methode onCreate() in MainActivity aufgerufen.

Eigenen Code fügen Sie i.d.R. innerhalb von onCreate ein, aber unterhalb der ersten zwei Zeilen.

Schauen Sie gern auch mal in die API der Klasse AppCompatActivity. Sie sehen dort, dass die Klasse auch von der abstrakten Klasse Context abstammt (siehe API). Dieser Klasse werden wir noch öfter begegnen, wenn es darum geht, die Activity einer Methode "mitzugeben".

Die Activity, die zu Beginn einer App gestartet wird, nennt man auch Root Activity. Erstaunlich viele Apps bestehen nur aus dieser einen Activity, da es üblich ist, auf mobilen Geräten viele "kleine" Applikationen zu haben, die eine spezifische Aufgabe übernehmen. Zu jeder Activity gehört eine entsprechende grafische Oberfläche, die man als View bezeichnet.

Hat man mehrere Activities innerhalb der App, bedient man sich den Intents, um von einer Activity in die nächste zu kommen (siehe Modul Intents). Wir gehen aber im weiteren von einer App mit einer einzigen Activity aus.

2.3 View: Grafische Oberfläche

Die grafische Oberfläche besteht aus Komponenten, die man in einem Layout anordnet. Die View wird in Form eines XML-Dokuments (z.B. activity_main.xml) spezifiziert, das im Verzeichnis res/layout vorliegt:

Projektsicht

In Android Studio sehen Sie zunächst die Design-Ansicht der Datei. Diese Ansicht erlaubt ein grafisches Editieren des Layouts:

Projektsicht

Links unten sehen Sie zwei Reiter (Tabs) namens Design und Text. Wenn Sie auf "Text" klicken, sehen Sie die Text-Ansicht der XML-Datei. Die Ansicht auf die Datei ist häufig notwendig, um Details zu prüfen und um die Funktionsweise des Layouts besser zu verstehen.

2.3.1 Exkurs: XML

XML ist eine Möglichkeit, strukturierte Daten darzustellen. Ein XML-Dokument besteht aus Elementen, wobei jedes Element einen öffnenden und einen schließenden Tag (wird englisch ausgesprochen, also /täg/) hat. Zum Beispiel könnte es ein foo-Element geben:

<foo>
  Hier kann irgendwas stehen.
</foo>

Ein Element kann andere Elemente enthalten:

<foo>
  Hier kann irgendwas stehen.
  <bar>
  </bar>
  <doo>
  </doo>
</foo>

Ein Element kann Attribute haben, die immer im öffnenden Tag stehen:

<foo size="150" color="blue" url="http://something.com">
  Hier kann irgendwas stehen.
</foo>

Manchmal ist es nicht nötig einen öffnenden und einen schließenden Tag zu haben. Das Element besteht quasi nur aus einem Tag. Dann signalisiert man das mit einem Slash am Ende:

<foo size="150" />

Man nennt einen solchen Tag auch einen Leer-Tag.

Eine ausführliche Beschreibung von XML finden Sie in Kapitel 1 meines Skripts zu Webtechnologien.

2.3.2 Text-Ansicht

Kehren wir zurück zu unserer Text-Ansicht des Layouts. Die Datei, die per Default erzeugt wird, sieht wie folgt aus. Die hat zwei Elemente (ConstraintLayout und TextView), wobei TextView in ConstraintLayout enthalten ist.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="de.hsa.myapp.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Löschen Sie das vorhandene TextView-Element, indem Sie

Anschließend ziehen Sie in der Design-Ansicht einen Button aus der Palette (Leiste links neben dem grafischen Fenster) und positionieren ihn in die Mitte. In der rechten Leiste können Sie den Text des Buttons ändern zu "Hallo". Sie können auch die Textgröße im Feld "textSize" ändern, z.B. auf "30sp".

Erste App im Editor

Wenn Sie in der Text-Sicht sind, können Sie zusätzlich den Preview aktivieren (Button ist ganz rechts im Rand des Gesamtfensters), so dass Sie sowohl XML als auch GUI im Blick haben. So können Sie auch beobachten, welche Änderungen sich ergeben, wenn Sie im XML editieren.

Text-Sicht mit Preview

2.4 Testen: Emulator verwenden

Wenn Sie Ihr Projekt starten, können Sie

Wir schauen uns Option zwei an und starten die App auf einem sogenannten Emulator. Dazu müssen Sie für den Emulator die Geräte installieren (unterschiedlichste Smartphone- und Tablet-Modelle).

Wollen Sie Ihre App auf einem echten Endgerät starten, müssen Sie das Gerät in den Entwicklungsmodus versetzen und das USB-Debugging aktivieren (dazu gibt es viele Anleitungen im Netz). Dann schließen Sie das Gerät per USB-Kabel an den Rechner an. Android Studio wird dann Ihr Smartphone/Tablet beim Start mit Run als Option anbieten.

Erste App im Emulator

Wir sehen hier, dass unser Button nach links oben gerutscht ist. Das heißt, wir müssen uns mit dem komplexen Thema Layout auseinander setzen, das verschärft wird durch die vielen unterschiedlichen Screen-Größen und durch den Unterschied der Portrait/Landscape-Orientierungen. Dazu in einem eigenen Kapitel mehr.

2.5 Interaktion: Auf Buttons reagieren

Wir möchten jetzt mit der App interagieren, d.h. dass eine Aktion des Users eine Reaktion in der App hervorruft. Als kleines Beispiel möchten wir, dass beim Druck auf den Button der Text des Buttons sich ändert zu "Welt".

Schauen wir uns in "activity_main" die Textansicht an. Wir sehen den Button in diesem Schnipsel:

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hallo"
    android:textSize="30sp"
    tools:layout_editor_absoluteX="133dp"
    tools:layout_editor_absoluteY="225dp" />

Wichtig ist der ID des Buttons.

android:id="@+id/button"

Diesen benötigen wir, wenn wir im Code von MainActivity.java darauf zugreifen wollen. Aber wie können wir vom Java-Code aus auf eine Komponente zugreifen, die in irgendeinem XML-File definiert ist? Die Antwort ist die Klasse R, die Android automatisch erzeugt und die über statische Variablen den Zugriff auf die IDs der Komponenten erlaubt.

Klasse R

In der Methode onCreate

protected void onCreate(Bundle savedInstanceState) {
  ...
}

verwenden wir die Methode findViewById, um die richtige Komponente herauszufischen. Bei gibt uns der Ausdruck "R.id.button" den ID des Buttons zurück.

Button halloButton = (Button)findViewById(R.id.button);

UPDATE: Seit API 26 benötigt die Methode findViewById kein Casting mehr. Dann wird daraus:

Button halloButton = findViewById(R.id.button);

Anschließend hängen wir ein Stück Code zur Ausführung an dieses Button-Objekt. Wir verwenden dazu eine sogenannte "anonyme innere Klasse", über die wir später noch reden werden:

halloButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        halloButton.setText("Welt");
    }
});

Aufgrund der Position des Code-Schnipsels "halloButton.setText("Welt")" innerhalb einer inneren Klasse, müssen wir die Variable halloButton "final" machen. Der komplette Code ist:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Button halloButton = findViewById(R.id.button);

    halloButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            halloButton.setText("Welt");
        }
    });
}

Wenn Sie jetzt die App starten und auf den Button klicken, sehen Sie, dass der Text zu "Welt" verändert wird. Ihr erste Interaktion!

2.6 Zusammenfassung

Jede App besteht aus einer Reihe von Activities. Man kann sich zunächst mal jede Activity als eine Screen einer App vorstellen. Jede Activity hat eine View, das sind alle grafischen Komponenten (Buttons, Texte, Bilder) und das dazugehörige Layout.

Im einfachsten Fall nehmen wir die eine vorgegebene Activity MainActivity.java. Sie ist unser Einstiegspunkt, hier wird in Java die Funktionalität der App programmiert. Das Layout definieren wir in der zur Activity gehörigen XML-Datei activity_main.xml. Dazu gibt es auch einen grafischen Editor, der uns dabei unterstützt (Design-Ansicht).

Wir testen unsere Apps in der Regel mit einem Emulator. Das ist ein Programm, das ein Smartphone oder ein Tablet auf unserem Computer simuliert. Wir können aber auch auf echten Endgeräten testen, die wir per USB-Kabel anschließen und die vorab in den Entwicklungsmodus geschaltet wurden.

Interaktion bedeutet, dass unsere App auf eine Aktion des Users reagiert, z.B. auf das Berühren eines Buttons. Dazu beziehen wir das Java-Objekt des Buttons mit Hilfe der Methode findViewById und der Klasse R, welche die IDs aller Komponenten enthält. Anschließend "hängen" wir einen sogenannten Listener an das Button-Objekt mit Hilfe der Methode setOnClickListener. In dem Listener-Code können wir z.B. grafische Komponente verändern, etwa einen neuen Text in eine Textkomponente schreiben.

2.7 Übungen

(A) Hallo-Button

Erzeugen Sie ein Projekt, wo Sie alle Schritte dieses Kapitels einbauen und testen, d.h. Sie haben eine erste App mit einem Hallo-Button. Der Button ändern beim Anklicken seine Schrift zu "Welt".

(B) Zweiter Button

Fügen Sie einen zweiten Button hinzu.

Ändern Sie die Beschriftung des Buttons zu "OK".

Ändern Sie den ID des Buttons zu "okButton".

Lassen Sie folgenden Code ausführen, wenn der Button gedrückt wird:

Toast.makeText(view.getContext(), "OK gedrückt", Toast.LENGTH_SHORT).show();

Starten Sie Ihre App und schauen Sie, was passiert, wenn Sie auf den Button drücken.

(C) Textfeld

Fügen Sie ein Textfeld hinzu (TextView), z.B. mit dem Text "Meine erste App", und platzieren Sie das Textfeld über dem Button. Was passiert, wenn Sie die App im Emulator laufen lassen?