X

Anmelden

Zur Bestätigung jetzt anmelden

Passwort vergessen?

... oder mit Facebook anmelden:

Du hast noch keinen Zugang zu AndroidPIT? Registrieren

Android Anfänger Workshop

Inhaltsverzeichnis

[Verstecken]

Einleitung

Hier findet ihr die deutsche Übersetzung meiner Präsentation "Android Beginners Workshop", die ich auf dem Mobile Monday m2d2 Developer Day in Düsseldorf am 23.02.2010 gehalten hab. Dieser Workshop richtet sich an Anfänger, die hier ihre erste "Hello World"-App erstellen werden.

Die wichtigsten Grundlagen

Basics

  • Android Apps werden in Java programmiert
  • Fast alle Java-Klassen stehen zur Verfügung plus Verschlüsselung, HTTP, JSON, XML Bibliotheken
  • Keine main()-Funktion - stattdessen: lose gekoppelte Komponenten, eine oder mehr davon als Einstiegspunkt definierbar
  • Wichtigste Komponente: "Activity" - entspricht einem sichtbaren Fenster auf dem Screen

Im folgenden Bild seht ihr drei Activities der Contacts/Dialer App. Gut zu sehen sind die zwei Einstiegspunkte: Die App kann über das Icon "Contacts" sowie über das Icon "Dialer" gestartet werden. Die App startet dann mit der entsprechenden Activity.

Datei:Beginners_Workshop_Contacts.png

Activity, View, Event, Intent

Datei:Beginners_Workshop_Activity.png

Activity

  • definiert eine "View", zur Anzeige auf dem Screen
  • behandelt "Events" (z. B. Klick auf einen Button)
  • benutzt "Intents", um andere Activities zu starten

View

  • eine "View" ist der sichtbare Teil der Activity
  • definiert in einer XML-Layout-Datei (oder im Code)

Event

  • wird ausgelöst, wenn etwas geschieht (z. B ein Button geklickt wird)
  • ruft eine Listener-Methode auf, sofern ein Listener definiert ist

Intent

  • startet eine andere Activity ("öffnet ein neues Fenster")
  • kann Daten an die zu startende Activity übergeben
  • kann Activities aus anderen Apps starten!

Activity Lifecycle

Resourcen auf dem Mobiltelefon sind limitiert. Daher muss das Android-Betriebssystem in der Lage sein, nicht aktive Activities (d. h. nicht im Vordergrund sichtbar), jederzeit zu beenden.

Jede Activity hat einen sogenannten Lifecycle ("Lebenszyklus"), der vom Betriebssystem gesteuert wird.

Datei:Beginners_Workshop_Activity_LC.png

Um Datenverlust oder den Verlust des Zustands einer Activity zu vermeiden, müssen die Daten/der Zustand der Activity gesichert werden, wenn diese pausiert (nicht mehr im Vordergrund, aber noch sichtbar) oder gestoppt (nicht mehr sichtbar) wird.

Einrichtung der Entwicklungsumgebung

Eclipse

Zunächst wird Eclipse benötigt. Die Installation von Eclipse wird hier jedoch nicht behandelt.

Android SDK Starter Package

Lade das SDK Starter Package für Dein Betriebssystem unter http://developer.android.com/sdk/index.html herunter und installiere es.

SDK Packages

Starte des SDK Starter Package (als Administrator unter Windows Vista / Windows 7). Beim ersten Start siehst Du eine Auswahl verfügbarer Pakete, die Du alle installieren solltest (alle SDK Plattformen und Dokumentation).

Zusätzlich solltest Du noch "Usb Driver Package" auswählen - damit kannst Du nachher Deine App aus Eclipse heraus direkt auf Deinem Android-Handy starten und debuggen:

Datei:Beginners_Workshop_SDK_Starter.png

ADT (Android Development Tools) Eclipse Plugin

Die folgende Beschreibung ist für Eclipse 3.5 (Galileo) und Eclipse 3.6 (Helios). Instruktionen für Eclipse 3.4 (Ganymede) gibt es unter http://developer.android.com/sdk/eclipse-adt.html.

  1. Wähle "Help" → "Install New Software".
  2. Im "Available Software"-Dialog, klicke den "Add"-Button...
  3. Im "Add Site"-Dialog, gib einen Namen ein (z. B. "Android Plugin") und die folgende URL als Location: https://dl-ssl.google.com/android/eclipse/ (probier "http", wenn "https" nicht funktioniert). Klick den "OK"-Button.
    Datei:Beginners_Workshop_ADT1.png
  4. Zurück im "Available Software"-Dialog, wähle die Checkbox neben "Developer Tools" und klicke "Next".
    Datei:Beginners_Workshop_ADT2.png
  5. Im "Install Details"-Dialog, klicke "Next", um die Lizenzvereinbarung zu akzeptieren und klick auf "Finish".
  6. Eclipse neustarten.
  7. Wähle "Window" → "Preferences".
  8. Im "Preferences"-Dialog, wähle "Android".
  9. Gib den SDK-Ordner ein (z. B. "C:\Programme\android-sdk-windows") und klicke auf "OK".

Entwicklung und Test einer "Hello World" App

Neues Projekt erstellen

Datei:Beginners Workshop New Project.png

Mit dem ADT-Assistenten wird ein neues Projekt erstellt:

Wähle "File" → "New" → "Project..."; im "New Project"-Dialog wähle "Android Project" aus dem "Android" Order.

Füll den "New Android Project"-Dialog wie folgt aus:

  • Project name: "Hello Workshop"
  • Verwende die "default location" oder lege eine andere Location fest
  • Build target: Android 1.6 (wir sorgen später für 1.5-Kompatibilität)
  • Application name: "Hello Workshop"
  • Package name: "de.test.hello"
  • Create Activity: "HelloWorkshopActivity"
  • Min SDK Version: "4"

Klicke auf den "Finish"-Button.

Der "New Project"-Assistent hat folgende Dateien und Ordner erstellt:

Datei:Beginners_Workshop_Files.png

HelloWorkshopActivity.java: Klasse der Haupt-Activity
R.java: Resourcen-ID-Definitionen (automatisch erstellt, nicht editieren!)
/assets: Ordner für Binär-Dateien (alles, was Android nicht selbst verwaltet)
/res: Ordner für Resource-Dateien (Bilder, Layouts, Strings, ...)
/res/drawable-hdpi/icon.png: Logo in hoher Auflösung (72 x 72 Pixel – 240 dpi)
/res/drawable-ldpi/icon.png: Logo in niedriger Auflösung (36 x 36 Pixel – 120 dpi)
/res/drawable-mdpi/icon.png: Logo in mittlerer Auflösung (48 x 48 Pixel – 160 dpi)
/res/layout/main.xml: Layout-Definition für View der Haupt-Activity
/res/values/strings.xml: String-Definitionen
AndroidManifest.xml: "Manifest"-Datei, definiert Infos wie Name, Logo und Haupt-Activity
default.properties: Projekt-Eigenschaften

AndroidManifest.xml

Datei:Beginners_Workshop_Manifest.png (Anklicken für Originalgröße)

Damit Handys mit hohen Auflösungen (z. B. Motorola Milestone) auch die hdpi-Resourcen verwenden, muss folgender Eintrag in die AndroidManifest.xml-Datei eingefügt werden:

<supports-screens android:anyDensity="true" />

Anonsten würden bei hohen Auflösungen die mdpi-Resourcen verwendet und hoch-skaliert werden.

Damit die App auf Handys mit großem Screen (Archos 5) oder kleinem Screen (HTC Tattoo) den kompletten Bildschirm ausfüllt bzw. überhaupt läuft müssen folgende Attribute dem zuvor eingefügten Element hinzugefügt werden:

<supports-screens android:anyDensity="true"
        android:largeScreens="true" 
        android:smallScreens="true" />

Ansonsten werden Handys mit großem Screen die App nur in einem kleinen Bereich anzeigen und Handys mit kleinem Screen werden die App nicht starten.

res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, HelloWorkshopActivity!</string>
    <string name="app_name">Hello Workshop</string>
</resources>

Definiert Strings, die in den Manifest- und Layout-Dateien referenziert wurden (könnten auch im Code referenziert werden):

android:label="@string/app_name"

ist äquivalent zu

android:label="Hello Workshop"

Natürlich nur solange wir keine strings.xml-Dateien in anderen Sprachen hinzufügen. Wenn Du Deine App lokalisieren willst, solltest Du Deine Strings immer in Resourcen-Dateien auslagern!

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>

Definiert ein (einfaches) Layout namens "main" (bloß ein Name, hat keine Bedeutung), welcher später in der Activity referenziert wird.

Das Layout sieht wie folgt aus:

Datei:Beginners_Workshop_MainLayout.png

R.java

Automatisch erstellt – definiert Integer-Konstanten für jede Resource. Diese Datei niemals editieren – man braucht sie eignetlich nicht mal einzusehen.

package de.test.hello;

public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int icon=0x7f020000;
    }
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class string {
        public static final int app_name=0x7f040001;
        public static final int hello=0x7f040000;
    }
}

HelloWorkshop2Activity.java

HelloWorkshop2Activity.java

package de.test.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloWorkshopActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Wichtig ist hier die letzte Zeile:

setContentView(R.layout.main);

Diese setzt das angegebene Layout als View dieser Activity. Die Konstante aus der R-Klasse referenziert das Layout, welches in der Datei main.xml definiert wurde.

Emulator ("Android Virtual Device") erstellen

Datei:Beginners Workshop CreateAVD.png

  • Klicke auf das "Android SDK and AVD manager"-Icon in der Icon-Leiste von Eclipse.
  • Klicke auf "New"
  • Im "Create new AVD"-Dialog, gib folgendes ein:
    - Name: "G1"
    - Target: "Android 1.6 - API Level 4"
    - SD Card Size: "1024" MiB
    - Skin: Built-in: "Default (HVGA)"
  • Dann klicke auf "Create AVD" (kann eine Weile - bis zu einigen Minuten - dauern)

App zum ersten Mal starten

  • Wähle "Run" → "Run" (oder drücke Strg + F11).
  • Im "Run As"-Dialog, wähle "Android Application" und klicke auf "OK".
  • Eclipse startet jetzt automatisch den "G1" Emulator, den wir gerade erstellt haben. Sollte es mehrere passende Emulatoren geben, erscheint zunächst ein entsprechender Auswahldialog.
  • Nach rund einer Minute solltest Du die App im Emulator sehen:

Datei:Beginners_Workshop_App1.png

Ziel für das Tutorial

Datei:Beginners Workshop Plan.png

Das wollen wir heute erreichen:

  • Eine View erstellen, die so aussieht wie die Grafik rechts.
  • Der User soll seinen Namen eingeben können.
  • Wenn der User auf einen der Buttons klickt und kein Name eingetragen wurde, soll sich Dialog mit einer Fehlermeldung angezeigt werden.
  • Wenn der User auf einen Button klickt und seinen Namen eingegeben hat,
    → soll der User mit einer Popup-Nachricht („Toast“) gegrüßt werden
    → soll sich die Begrüßung am oberen Bildschirmrand ändern.

Komponenten hinzufügen

Füge ein „Enter your name“-Textfeld unter die ersten TextView-Komponente ein:

<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="20dp"
    android:text="@string/enter_your_name"
    />

Eclipse wird jetzt eine Fehlermeldung anzeigen: „No resource found that matches the given name (at 'text' with value '@string/enter_your_name').

Füge die fehlende Resource zu der Datei strings.xml hinzu:

<string name="enter_your_name">Enter your name:</string>

Die Fehlermeldung in main.xml wird jetzt verschwinden.

Füge ein Eingabefeld unter der „Enter your name“-Komponente ein:

<EditText
    android:id="@+id/name_field"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />

Die erste Zeile weist der Komponente die ID „name_field“ zu.

Unter dem Namens-Feld wollen wir die Buttons nebeneinander anordnen. Dazu benötigen wir ein LinearLayout mit horizontaler Orientierung und darin die zwei Buttons.

Inneres LinearLayout mit zwei Buttons:

<LinearLayout 
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
     >
    <Button 
        android:id="@+id/hi_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hi_button" 
        />
    <Button 
        android:id="@+id/hello_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/hello_button" 
        />
</LinearLayout>

Füge die Button-Texte in die strings.xml-Datei ein:

<string name="hi_button">Say Hi!</string>
<string name="hello_button">Say Hello!</string>

Schauen wir uns das Layout einmal an!

Auf der "main.xml"-Seite in Eclipse, klicke auf den "Layout"-Reiter am unteren Rand und Du wirst folgendes sehen:

Datei:Beginners_Workshop_App2.png

Activity erweitern

Nun erweitern wir unsere Activity. Öffne "HelloWorkshopActivity.java" und füge folgende Felder am Beginn der Klasse ein:

private Button hiButton;
private Button helloButton;

Am Ende der onCreate-Methode, füge folgenden Code ein:

hiButton = (Button)findViewById(R.id.hi_button);
hiButton.setOnClickListener(this);
helloButton = (Button)findViewById(R.id.hello_button);
helloButton.setOnClickListener(this);

Eclipse meldet nun dass HelloWorkshopActivity das Interface OnClickListener nicht implementiert. Klick auf die Fehlermeldung und wähle "Let 'HelloWorkshopActivity' implement 'OnClickListener'."

Nun zeigt Eclipse an, dass HelloWorkshopActivity die OnClickListener-Methoden nicht definiert. Klick auf die Fehlermeldung und wähle "Add unimplemented methods".

Wenn der User auf einen der Buttons klickt, müssen wir zunächst prüfen, ob er seinen Namen eingegeben hat. Füge folgenden Code in die „onClick“-Methode ein:

EditText nameField = (EditText) findViewById(R.id.name_field);
String name = nameField.getText().toString();
if (name.length() == 0) {
    new AlertDialog.Builder(this) 
            .setMessage(R.string.error_name_missing)
            .setNeutralButton(R.string.error_ok, null)
            .show();
    return;
}

Füge die zwei oben referenzierten Strings sowie zwei weitere in die strings.xml-Datei ein:

<string name="error_name_missing">Please enter your name.</string>
<string name="error_ok">OK</string>
<string name="hi_greeting">Hi %s!</string>
<string name="hello_greeting">Hello %s!</string>

Der User hat seinen Namen eingetragen. Nun zeigen wir die Begrüßung an:

if (v == hiButton || v == helloButton)
{
    int resourceId = v == hiButton ? R.string.hi_greeting
            : R.string.hello_greeting; 

    String greeting = getResources().getString(resourceId, name);
    Toast.makeText(this, greeting, Toast.LENGTH_LONG).show();
}

Schließlich wollen wir die Begrüßung am oberen Bildschirmrand ändern. Um den Text der Komponente zu ändern, müssen wir ihr zunächst eine ID zuweisen. Bearbeite die main.xml-Datei und füge wie folgt eine ID in das erste TextView-Element ein:

<TextView  
    android:id="@+id/greeting_field"
    … />

Die zuvor erstellte Methode wird nun erweitert:

if (v == hiButton || v == helloButton)
{
    int resourceId = v == hiButton ? R.string.hi_greeting
            : R.string.hello_greeting;

    String greeting = getResources().getString(resourceId, name);
    Toast.makeText(this, greeting, Toast.LENGTH_LONG).show(); 

    TextView greetingField = (TextView) findViewById(R.id.greeting_field);
    greetingField.setText(greeting);
}

Und nun? Wir sind fertig – starte das Projekt!

Projekt starten

Starte das Projekt wie zuvor (am einfachsten mit Strg + F11), hier sind ein paar Screenshots:

Projekt kompatibel zu Android 1.5 machen (z. B. HTC Hero)

In Android 1.6 wurden unterschiedliche Bildschirmauflösungen und Pixeldichten eingefügt. Für Android 1.5 und älter sind die Ordner „drawable-hdpi“, drawable-ldpi“, „drawable-mdpi“ unbekannt.

  • Ordner "drawable-hdpi" in "drawable-hdpi-v4" umbenennen, so dass Android 1.5 und älter ihn ignorieren
  • Ordner "drawable-ldpi" in "drawable-ldpi-v4" umbenennen, so dass Android 1.5 und älter ihn ignorieren
  • Ordner "drawable-mdpi" in "drawable" umbenennen, so dass Android 1.5 und früher ihn sehen

In der AndroidManifest.xml-Datei, ändere die Zeile

    <uses-sdk android:minSdkVersion="4" />

in

    <uses-sdk android:minSdkVersion="3" targetSdkVersion="4" />

Wie geht es weiter?

  • Erstelle verschiedene Layouts für verschiedene Bildschirm-Orientierungen (horizontal, vertikal)
  • Füge eine zweite Activity hinzu und starte sie aus der bestehenden Activity heraus (z. B. durch Klicken eines neuen Buttons)

Anhang - Quellcodes

HelloWorkshopActivity.java:

package de.test.hello;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
 
public class HelloWorkshopActivity extends Activity
        implements OnClickListener {
 
    private Button hiButton;
    private Button helloButton;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        hiButton = (Button) findViewById(R.id.hi_button);
        hiButton.setOnClickListener(this);

        helloButton = (Button) findViewById(R.id.hello_button);
        helloButton.setOnClickListener(this);
    }

    public void onClick(View v) {
        EditText nameField = (EditText) findViewById(R.id.name_field);
 
        String name = nameField.getText().toString();
 
        if (name.length() == 0) {
            new AlertDialog.Builder(this).setMessage(
                    R.string.error_name_missing).setNeutralButton(
                    R.string.error_ok,
                    null).show();
            return;
        }

        if (v == hiButton || v == helloButton) {
            int resourceId = v == hiButton ? R.string.hi_greeting
                    : R.string.hello_greeting;

            String greeting = getResources().getString(resourceId, name);
            Toast.makeText(this, greeting, Toast.LENGTH_LONG).show();

            TextView greetingField = (TextView) findViewById(R.id.greeting_field);
            greetingField.setText(greeting);
        }
    }

}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:id="@+id/greeting_field"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="20dp"
    android:text="@string/enter_your_name"
    />
<EditText
    android:id="@+id/name_field"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />

    <LinearLayout 
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
        <Button
            android:id="@+id/hi_button"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:text="@string/hi_button"
            android:layout_weight="1"
            /> 
        <Button
            android:id="@+id/hello_button"
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:text="@string/hello_button"
            android:layout_weight="1"
            /> 
    </LinearLayout>
    
</LinearLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, HelloWorkshopActivity!</string>
    <string name="app_name">Hello Workshop</string>
    <string name="enter_your_name">Enter your name:</string>
    
    <string name="hi_button">Say Hi!</string>
    <string name="hello_button">Say Hello!</string>

    <string name="error_name_missing">Please enter your name.</string>
    <string name="error_ok">OK</string>
    
    <string name="hi_greeting">Hi %s!</string>
    <string name="hello_greeting">Hello %s!</string>
</resources>
Anzeige

Bookmark / E-Mail

Klicke auf ein Icon, um diese Wiki-Seite zu bookmarken.
» Diesen Artikel per E-Mail versenden