Das Einsteigertutorial: Android-Apps selbstgemacht

TwitterActivity

All das führen wir nun in der TwitterActivity zusammen, deren in Listing 4 dargestellten Quellcode wir unter dem Namen TwitterActivity im Paket de.twitterclient ablegen. Initialisiert wird diese in der onCreate()-Methode, in der wir alle Elemente mit ihrer nötigen Funktion ausstatten.

Zunächst einmal teilen wir unserer TwitterActivity durch einen Aufruf von setContentView()mit, welches Layout sie verwenden soll. Eclipse legt für uns dabei automatisch die Klasse R an, welche Verweise auf all unsere Ressourcen enthält. Anschließend suchen wir über findViewById()unsere ListView heraus, der wir zuvor im Layout die ID list zugewiesen hatten, und geben ihr einen OnItemClickListener mit auf den Weg. Dessen onItemClick()-Methode wird aufgerufen, sobald ein Eintrag der Liste durch den Nutzer gedrückt wird. Darin erzeugen wir einen sogenannten Intent, der bewirkt, dass die Detailseite des Tweets im Browser des Geräts geöffnet wird. Intents werden näher im zugehörigen Kasten beschrieben. Ähnlich verfahren wir mit unserem Button, jedoch weisen wir diesem einen OnClickListener zu, der bewirkt, dass bei Klick auf den Button die loadTweets()-Methode aufgerufen wird.

Listing 4
public class TwitterActivity extends Activity {
    private static final Uri twitterUri = Uri.parse("http://api.twitter.com/1/statuses/user_timeline.json?screen_name=InsertEffect");
    private HttpClient client;
    private ListView listView;
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.twitter);

        client = new DefaultHttpClient();
        listView = (ListView) findViewById(R.id.list);
        listView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView> adapterView, View view, int position, long id) {
                Tweet tweet = (Tweet) adapterView.getItemAtPosition(position);

                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse(
                    "http://twitter.com/#!/InsertEffect/status/" + 
                    tweet.getId()
                ));
                startActivity(intent);
            }
        });
        Button updateButton = (Button) findViewById(R.id.button);
        updateButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                loadTweets(twitterUri);
            }
        });
        loadTweets(twitterUri);
    }
    private void loadTweets(Uri uri) {
        AsyncTask> task = new TwitterTask();
        task.execute(uri);
    }
    private class TwitterTask extends AsyncTask> {
        protected void onPostExecute(List result) {
            listView.setAdapter(new TweetAdapter(TwitterActivity.this, result));
        }
        protected List doInBackground(Uri... arg0) {
            try {
                HttpGet get = new HttpGet(arg0[0].toString());
                HttpResponse response = client.execute(get);
                String result = EntityUtils.toString(response.getEntity());

                JSONArray array = new JSONArray(result);
                ArrayList tweets = new ArrayList(array.length());

                for(int i=0; i 

In der loadTweets()-Methode schließlich laden wir den Twitter-Stream eines bestimmten Twitter-Nutzers von einer fest definierten URI. Hierbei gilt es zu beachten, dass die komplette Nutzeroberfläche in Android grundsätzlich in einem einzelnen Thread ausgeführt wird, dem sogenannten UI-Thread. Blockiert man diesen Thread durch länger andauernde Operationen, z.B. durch HTTP-Anfragen, friert für die Dauer der Operation die komplette Oberfläche der Anwendung ein. Um dies zu verhindern, müssen wir derartige Operationen in einen zweiten Thread auslagern, was wir beispielsweise mithilfe der AsyncTask-Klasse tun können. Innerhalb unserer doInBackground()-Implementierung können wir ungestört unsere HTTP-Anfrage durchführen, deren Ergebnis anschließend über die onPostExecute()-Methode zurück an den UI-Thread übergeben wird. Dort statten wir unsere ListView mit einem neuen TweetAdapter aus, der die zuvor abgefragte Liste von Tweets enthält. Um die HTTP-Anfrage auszuführen, nutzen wir die HttpComponents-Bibliothek von Apache, welche jeder Android-Installation beiliegt.

Android Manifest

Damit Android weiß, welche Activities bzw. welche Komponenten in einer Anwendung enthalten sind, müssen wir diese noch in der AndroidManifest.xml deklarieren, die sich im Root-Verzeichnis unseres Projekts befindet. Das fertige Manifest für unseren Twitter-Client ist in Listing 5 dargestellt. Darin deklarieren wir einen Activity-Knoten, der als name-Attribute den Namen unserer TwitterActivity-Klasse enthält. Zusätzlich deklariert diese einen sogenannten Intent-Filter, der genutzt wird, um Komponenten für ausgehende Intents zu finden. Der hier deklarierte Filter gibt die Activity an, die für unsere App im Home-Screen des Nutzers aufgeführt werden soll. Außerdem müssen wir noch die nötige Permission anfordern, um Internetzugriff zu erhalten. Permissions müssen vom Nutzer bestätigt werden, wenn er die App installiert.

Sobald das Manifest angepasst ist, können wir unsere neu geschaffene App über Strg+F11 starten.

Listing 5
Intents

Intents spielen eine große Rolle in Android, zu groß, um sie hier im Detail zu erklären. Im Wesentlichen dienen Intents dazu, einzelne Komponenten, wie zum Beispiel Activities, in Android anzusprechen. Das können Komponenten der eigenen Anwendung sein, aber auch Komponenten des Betriebssystems oder anderer Anwendungen. Beispielsweise könnten wir über Intents eine Activity anfordern, die in der Lage ist, Emails zu verschicken, ohne die konkrete Email-Anwendung kennen zu müssen.

Jede Anwendungs-Komponente (mit Ausnahme von Content-Providern) lässt sich über Intents ansprechen, indem diese einen passenden Intent-Filter im Manifest der Anwendung deklariert. Setzt eine andere Anwendung einen passenden Intent für eine entsprechende Komponente ab, kann diese auf verschiedenen Wegen auf die Komponenten zugreifen, beispielsweise die jeweilige Activity anzeigen oder einen Service ausführen.

Fazit

Unsere kleine Twitter-App wird sicher keinen Schönheitspreis gewinnen, was nicht zuletzt an dem etwas bescheidenen Default-Look-and-Feel von Android liegt. Um die App in Sachen Optik und Nutzerführung auf den neuesten Stand zu bringen, ist leider viel Handarbeit nötig. Das machen andere Plattformen wie iOS und Windows Phone 7 besser.

Die eigentliche Genialität von Android spielt sich jedoch hinter den Kulissen ab: Während andere Plattformen erst anfangen, über Multitasking nachzudenken und nicht einmal gemeinsamen Speicherplatz für Apps anbieten, hat Android mit seinen Intents eine hochflexible Technologie geschaffen, die Apps auf vielfältige Art und Weise miteinander interagieren lässt. So müssen wir nicht etwa unsere App verlassen, um unsere Tweets im Browser ansehen zu können, sondern können diesen direkt in den Workflow unserer App integrieren.

Letztendlich steht Android noch am Anfang seiner Laufbahn und wird mit Hochdruck verbessert und erweitert. Besonders die kommenden 3.x-Versionen versprechen zahlreiche Neuerungen, inbesondere im UI-Bereich. Wer mit dieser rasanten Entwicklung mithalten will, wird stets am Ball bleiben müssen, kann sich dafür aber auch sicher sein, dass die Arbeit mit Android so schnell nicht langweilig werden wird. Ein guter Einstiegspunkt ist hierbei die offizielle Dokumentation, die neben Klassenbeschreibungen auch zahlreiche Artikel und Codebeispiele beinhaltet [6].

Timo Ohr arbeitet als Entwickler bei der InsertEFFECT GmbH in Nürnberg, die sich auf die Entwicklung von mobilen Anwendungen und Webseiten spezialisiert hat. Seine Kompetenzen liegen in den Bereichen Android- und Javaentwicklung.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.