Android_Tutorial_Lektion25_fotolia_RA_Studio_46292813

Programmier Tutorial: Apps für Android entwickeln – Teil 25: Auslesen und Verarbeiten der Daten mit einem JSON-Parser

Wir werden in dieser Lektion die vom Webserver zurück erhaltenen online Daten in unserer App weiterverarbeiten. Dazu werden wir die Zitatdaten aus der erhaltenen JSON-Zeichenkette auslesen (parsen) und mit ihnen den ListView unserer Android App füllen.

Dieser Prozess wird im asynchronen Task ausgeführt werden, damit der UI-Thread von der Berechnung nicht blockiert wird. Dadurch bleibt die Benutzeroberfläche unserer App stets flüssig bedienbar, auch wenn die Bearbeitungszeit einmal mehrere Sekunden beträgt.


Im theoretischen Teil dieser Lektion werden wir das JSON-Format näher kennenlernen und erfahren, mit welchen Werkzeugen JSON-Daten in Android effektiv ausgelesen und weiterverarbeitet werden können. Dabei werden wir auch auf den Aufbau unserer Zitatdaten genauer eingehen.

Anschließend werden wir im praktischen Teil dieser Lektion zusätzliche Bilddateien, Autorenbilder für weitere acht deutsche Lyriker, unserem Android Studio Projekt hinzufügen. Danach werden wir die Parsing-Methode für JSON-Daten createQuotesFromJSONString() in der Utility-Klasse implementieren.

Mit ihrer Hilfe werden wir die Zitatdaten aus der vom Webserver übermittelte JSON-Zeichenkette auslesen und daraus eine Quotes-Liste erzeugen. Die neue Parsing-Methode lassen wir von dem asynchronen Task in der MainActivity-Klasse aufrufen, wodurch das Verarbeiten der Zitatdaten in einem eigenen Hintergrund-Thread ausgeführt wird.

Abschließend werden wir unsere Android App im Emulator auf einem Android Virtual Device ausführen und prüfen, ob die erhaltenen JSON-Zitatdaten korrekt ausgelesen, in eine Quotes-Liste umgewandelt und schließlich im ListView unserer App ausgegeben werden.

1. Wie JSON-Daten in Android verarbeitet werden

Unsere Anwendung soll zwei verschieden Datenformate verarbeiten können. Diese sind das JSON-Format, welchem wir uns in dieser Lektion zuwenden, und das XML-Format, das wir in der nächsten Lektion behandeln werden.

Für das Übertragen der Zitatdaten von dem Webserver zu unserer Android App verwenden wir im Moment das JSON-Format, welches für JavaScript Object Notation steht. Dieses schlanke und für Menschen leicht zu lesende Datenaustauschformat, zeichnet sich besonders durch seine vielseitige Nutzbarkeit aus.

Zudem kann man es sehr einfach in Android und vielen anderen Programmiersprachen parsen (Analysieren der Datenstruktur) und generieren lassen, was für unsere Anwendung besonders vorteilhaft ist.

1.1 Das JSON-Format im Überblick

Das JSON-Format wird hauptsächlich zur Übertragung und zum Speichern von strukturierten Daten eingesetzt. Besonders oft wird es bei Webanwendungen und mobilen Apps in Verbindung mit JavaScript, Ajax oder WebSockets zum Transfer von Daten zwischen dem Client und dem Server verwendet.

Dabei zeichnet es sich besonders als ein sehr kompaktes Datenformat aus, welches eine einfach lesbare Textform besitzt und vorwiegend auf den schnellen Datenaustauschs zwischen Anwendungen optimiert ist. Für jedes gültige JSON-Dokument gilt, dass es gleichzeitig auch ein gültiges JavaScript ist, welches per eval() Anweisung interpretiert werden kann.

Das JSON-Format baut auf zwei Strukturen auf:

  • Objekten – Bei JSON werden Objekte innerhalb geschweifter Klammern { } definiert. Sie enthalten eine durch Kommata geteilte, ungeordnete Liste von Eigenschaften. Jede dieser Eigenschaften besteht aus einem Schlüssel (Key) und einem Wert (Value), welche durch einen Doppelpunkt (Schlüssel:Wert) voneinander getrennt werden.

    Die Schlüssel sollten eindeutig sein, da unterschiedliche Parser mit mehrfach vorkommenden Schlüsseln unterschiedlich umgehen. Die Schlüssel sind vom Datentyp String (Zeichenkette). Die Werte können von folgende Datentypen sein: null, true, false, number, string, object und array.

  • Arrays – Bei JSON werden Arrays innerhalb eckiger Klammern [ ] definiert. Ein Array enthält eine durch Kommata geteilte, geordnete Liste von Werten gleichen oder verschiedenen Typs.

In dem unteren Code ist ein typisches JSON-Dokument mit seinen möglichen Datentypen aufgeführt:

{
  "Autor": "Arthur Schopenhauer",
  "Alter": 72,
  "Kinder": [],
  "Partner": null,
  "Hauptwerk":
  {
    "Titel": "Die Welt als Wille und Vorstellung",
    "Digitalisiert": true,
    "Auflagen": [1819, 1844, 1859],
    "Verleger": "Brockhaus"
  }
}

Das oben aufgeführte JSON-Dokument beschreibt ein Objekt, welches fünf Eigenschaften besitzt, die über Schlüssel/Wert-Paare definiert sind. Die Schlüssel Autor, Alter und Partner haben Werte von einfachem Datentyp zugewiesen bekommen. Der Schlüssel Kinder enthält einen leeren Array.

Dem Schlüssel Hauptwerk wurde als Wert ein Objekt zugewiesen, welches selbst über vier Eigenschaften verfügt. Auch diesmal sind die Eigenschaften in Form von Schlüssel/Wert-Paaren definiert. Es sind die folgenden vier Schlüssel Titel, Digitalisiert, Auflagen und Verleger vorhanden.

Für das Auslesen der JSON-Daten in Android ist die genaue Kenntnis der vorliegenden Datenstruktur unerlässlich. Daher werden wir nun einen genaueren Blick auf die Struktur unserer Zitatdaten werfen.

1.2 Aufbau und Struktur der JSON-Zitatdaten unserer Android App

Wir werden nun die Datenstruktur der JSON-Daten unserer Android App, also die Struktur der Zitatdaten, genauer untersuchen. Ziel ist es zu verstehen, wie die Zitatinformationen in dem vom Webserver erhaltenen JSON-Dokument strukturiert sind, um sie später auslesen zu können.

In dem unteren Code ist der Inhalt einer typischen Antwort unseres Webservers auf eine HTTP-Anfrage, wie bspw. https://www.codeyourapp.de/tools/query.php?count=3&mode=0, aufgeführt:

{
  "diagnostics": { "count": 3, "mode": 0, "created": "2019-02-08 16:02:53" },
  "quotes": [
    {
      "id": "herder",
      "author": "Johann Gottfried Herder",
      "text": "Naturwissenschaft und Naturlehre muß ein Knabe lernen ..."
    },
    {
      "id": "schopenhauer",
      "author": "Arthur Schopenhauer",
      "text": "Es ist wirklich unglaublich, wie nichtssagend und bedeutungsleer ..."
    },
    {
      "id": "jean_paul",
      "author": "Jean Paul",
      "text": "Die Leidenschaft macht die besten Beobachtungen und die ..."
    }
  ]
}

In der oben angegebenen Antwort des Webservers wird im JSON-Format ein Objekt definiert, welches zwei Eigenschaften besitzt. Diese besitzen die Schlüssel diagnostics und quotes. Dem diagnostics-Schlüssel ist als Wert ein Objekt mit drei Eigenschaften zugewiesen worden, das für Diagnosezwecke ausgewertet werden kann.

Dem quotes-Schlüssel wurde eine Array zugewiesen, welcher mehrere Objekte in sich als seine Elemente aufgenommen hat. Jedes Array-Element repräsentiert ein Zitat (Quote) und besitzt drei Eigenschaften, die wieder über Schlüssel/Wert-Paare definiert werden. Der id-Schlüssel enthält die eindeutige Autoren-ID. Der author-Schlüssel den vollständigen Namen des Autors. Und der text-Schlüssel enthält den Inhalt des Zitats.

Möchten wir also auf die Zitatinformationen in dem oben aufgeführten JSON-Dokument zugreifen, müssen wir zuerst auf den quotes-Array zugreifen und anschließend dessen Elemente der Reihe nach durchlaufen. Dabei können wir zu jedem Array-Element die Informationen über die Autoren-ID, den Autorennamen und den Zitatinhalt auslesen und in entsprechenden Variablen zwischenspeichern.

1.3 Auslesen und Verarbeiten unserer JSON-Daten in Android

Das JSON-Format mit seiner universellen Datenstrukturen ist hervorragend zum Auslesen und Weiterverarbeiten geeignet. Mittlerweile existieren in praktisch allen verbreiteten Sprachen sog. Parser, mit deren Hilfe der Inhalt von JSON-Dokumente einfach und effektiv ausgelesen werden kann.

Dies gilt auch für die Programmiersprache Java, für die ein JSON-Parser in dem org.json Package implementiert wurde. Dieser Parser kann auch in Android ohne das Einbinden zusätzlicher Bibliotheken verwendet werden.

Wie der JSON-Parser in Android verwendet wird, zeigt folgendes Quellcode-Beispiel:

public static List<Quote> parseJSONString(String jsonString) {

    List<Quote> receivedQuoteList = new ArrayList<>();

    try {
        JSONObject jsonObj = new JSONObject(jsonString);

        // Anforderen des JSON-Objekts mit den Diagnosedaten
        JSONObject diagnostics = jsonObj.getJSONObject("diagnostics");

        int count = diagnostics.getInt("count");
        int mode = diagnostics.getInt("mode");
        String dateCreated = diagnostics.getString("created");

        // Anforderen des JSON-Array Knotens mit den Quotes-Objekten
        JSONArray quotes = jsonObj.getJSONArray("quotes");

        // Durchlaufen des Quotes-Arrays und Auslesen der Daten jedes Quote-Objekts
        for (int i = 0; i < quotes.length(); i++) {
            JSONObject quote = quotes.getJSONObject(i);

            String imageId = quote.getString("id");
            String quoteAuthor = quote.getString("author");
            String quoteText = quote.getString("text");

            receivedQuoteList.add(new Quote(quoteText, quoteAuthor, imageId));
        }

    } catch (JSONException e) {
        Log.e(TAG, "JSONException: " + e.getMessage());
    }

    return receivedQuoteList;
}

Mit dem oberen Quellcode wird der gesamte Inhalt des JSON-Dokuments ausgelesen, welches von unserem Webserver generiert wurde und die im vorherigen Abschnitt beschriebenen Zitatinformationen enthält. Wir werden nun auf die wichtigsten Parsing-Methoden eingehen.

In Zeile 6 wird ein JSON-Objekt mit Hilfe des Konstruktors erzeugt. Diesem wird der JSON-String übergeben, welcher die vom Webserver übermittelten Zitatdaten enthält. Dieses JSON-Objekt besitzt die beide Eigenschaften mit den Schlüsseln diagnostics und quotes.

Dem diagnostics-Schlüssel wurde als Wert ein Objekt zugewiesen worden. Auf dieses Objekt greifen wir in Zeile 9 mit dem Methodenaufruf jsonObj.getJSONObject(„diagnostics“); zu. Als Rückgabewert erhalten wir ein JSON-Objekt, das drei Eigenschaften mit den Schlüsseln count, mode und created besitzt.

Jedem dieser drei Schlüssel ist eine einfacher Datenwert zugewiesen worden. Die Werte können wir mit den Methoden getInt() und getString() auslesen. Dabei müssen wir beim Methodenaufruf den jeweiligen Schlüssel als Argument übergeben. Dies geschieht in den Zeilen 11, 12 und 13.

Kommen wir nun zu dem quotes-Schlüssel. Diesem wurde als Wert ein Array zugewiesen. Auf den Array greifen wir in Zeile 16 mit dem Methodenaufruf jsonObj.getJSONArray(„quotes“); zu. Als Rückgabewert erhalten wir einen JSON-Array, der mehrere JSON-Objekte in sich aufgenommen hat.

Die Elemente des JSON-Arrays können wir nun der Reihe nach durchlaufen und deren Inhalte auslesen. Dies geschieht mit Hilfe einer for-Schleife in den Zeilen 19 bis 27. Auf die Array-Elemente, die JSON-Objekte, wird mittels der getJSONObject() Methode in Zeile 20 zugegriffen. Die Methode wird auf dem aktuellen Array-Objekt aufgerufen und erhält als Argument die Nummer des aktuellen Array-Elements.

Jedes dieser Array-Elemente ist ein JSON-Objekt, das die drei Eigenschaften mit den Schlüsseln id, author und text besitzt. Auch in diesem Fall sind den drei Schlüsseln primitive Datenwerte zugewiesen worden, auf die wir mit der Methode getString() und dem jeweiligen Schlüssel als Argument zugreifen können.

Mit den so ausgelesenen Zitatinformationen wird in Zeile 26 ein Quote-Objekt erzeugt und dieses einer Liste hinzugefügt, die später von dem ListView unserer Android App dargestellt werden kann.

Auf diese einfache Weise können in Android JSON-Daten verarbeitet werden. Dabei ist besonders wichtig die Datenstruktur des JSON-Dokuments genau zu kennen, da nur mit Hilfe der jeweiligen Schlüssel auf die Werte zugegriffen werden kann. Es muss auch unbedingt darauf geachtet werden, um was für einen Datentyp es sich bei dem jeweiligen Wert handelt, da unterschiedliche Datentypen mit unterschiedlichen Methode ausgelesen werden müssen.

Wir schließen nun den theoretischen Teil dieser Lektion ab und werden das Gelernte in die Praxis umsetzen. Dazu werden wir eine Parsing-Methode in der Utility-Klasse implementieren. Doch bevor wir dies tun, werden wir im nächsten Abschnitt noch einige Bilddateien unserem Android Studio Projekt hinzufügen.

2. Einfügen weiterer Bilddateien in das Projekt

Wir werden nun acht weitere Bilddateien als App Ressourcen unserem Android Studio Projekt hinzufügen. Dies ist erforderlich, da unser Webserver Zitate von zehn verschiedenen Autoren generieren kann und unsere App bisher nur über Autorenbilder von Goethe und Schiller verfügt. Die Bilddateien werden wir in den drawable/ Ordner einfügen und später als Autorenbilder verwenden.

Bevor wird die Bilddateien als App Ressourcen in unser Android Projekt einfügen können, müssen wir sie folgendermaßen herunterladen:

  1. Mit der linken Maustaste klicken wir jeweils auf die folgenden Links: Heine, Herder, Hölderlin, Jean Paul, Keller, Nietzsche, Schopenhauer und Wieland.
  2. Es öffnet sich ein neuer Tab mit dem jeweiligen Autorenbild. Wir klicken mit der rechten Maustaste auf das Bild.
  3. In dem aufgehenden Kontext-Menü klicken wir auf den Bild speichern unter… Eintrag.
  4. Anschließend speichern wir die Bilder unter den Dateinamen heine.png, herder.png, hoelderlin.png, jean_paul.png, keller.png, nietzsche.png, schopenhauer.png und wieland.png in einem beliebigen Ordner ab.

Die Bilddateien sollten nun in einem Ordner auf eurem Rechner abgespeichert worden sein. Wir werden diese Dateien in den nächsten Schritten unserem Projekt hinzufügen. Dazu muss Android Studio geöffnet sein und in dem Project Tool Window muss die Project-Ansicht ausgewählt sein.

Wir werden nun den drawable-Ordner unseres Projekts im Explorer wie folgt öffnen:

  1. Wir klicken mit der rechten Maustaste auf den drawable/ Ordner unseres Projekts in Android Studio.
  2. Anschließend klicken wir im Kontext-Menü auf den Show in Explorer Eintrag.
json_show_folder

Öffnen des drawable/ Ordners im Explorer

Es öffnet sich der res/ Ordner in einem neuen Explorer-Fenster. In diesem Ordner klicken wir doppelt auf den drawable/ Ordner, wodurch wir in diesen hinein navigieren:

json_res_folder

In dem res/ Ordner unseres Projekts klicken wir doppelt auf den drawable/ Ordner

Wir kopieren nun die acht heruntergeladenen Dateien heine.png, herder.png, hoelderlin.png, jean_paul.png, keller.png, nietzsche.png, schopenhauer.png und wieland.png in den drawable/ Ordner (Markierung A) hinein. Das Ergebnis sollte bei euch folgendermaßen aussehen:

drawable_folder_8_pictures

In dem drawable/ Ordner wurden 8 weitere Bilddateien hinein kopiert

Die 8 Bilddateien haben wir nun unserem Android Projekt als Drawable-Ressource hinzugefügt. Wir können ab jetzt per Quellcode oder von einer XML-Layout Datei aus auf diese App Ressourcen zugreifen.

In Android Studio sollte die eingefügten Bilddateien jetzt unter dem drawable/ Ordner aufgeführt werden:

8_drawable_resources_added

Die 8 weiteren Bilddateien sind nun unter dem drawable/ Ordner aufgeführt

Mit dem Hinzufügen dieser 8 Drawable-Ressourcen sind nun die Vorbereitungen an unserem Android Projekt abgeschlossen. Wir können jetzt mit dem Implementieren der Parsing-Methode in der Utility-Klasse beginnen.

3. JSON-Parsing Methode in Utility-Klasse implementieren

Momentan kann unsere Android App eine HTTP-Anfrage an den Webserver stellen und dessen Antwort, ein JSON-Dokument das Zitatdaten enthält, in einer Zeichenkette speichern. Die erhaltene Zitatdaten werden bisher jedoch noch nicht von unserer Anwendung ausgewertet. Dies werden wir nun ändern und eine neue Methode in der Utility-Klasse definieren.

Die neue Methode wird die vom Webserver erhaltenen Zitatdaten auslesen und daraus Quote-Objekte erstellen. Die erstellen Quote-Objekte werden in einer Liste abgelegt, welche schließlich an den Aufrufer zurückgegeben wird. Die so erstellte Liste mit Quote-Objekten kann dann vom ListView unserer Android App als Datenquelle verwendet werden.

Wir werden nun die Methode createQuotesFromJSONString() in der Utility-Klasse implementieren. Dazu öffnen wir die Klassendatei Utility.java im Editor von Android Studio, indem wir doppelt auf ihren Dateinamen im Project Tool Window klicken. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.zitate unseres Projekts.

In dem unteren Quellcode der Utility.java Datei sind die erforderlichen Maßnahmen bereits durchgeführt und die eingefügten Codezeilen grau markiert worden:

An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie im geschützten Bereich von ProgrammierenLernenHQ fortsetzen, in welchem sich alle Lektionen unserer Android Online-Kurse befinden.

Unsere Android Kurse bestehen aus insgesamt 43 großen Lektionen und sind unterteilt in 13 frei zugängliche und 30 Premium-Lektionen. Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer unseres Android Online-Kurs Gesamtpaket zugänglich.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813 An dieser Stelle endet der freie Inhalt dieser Lektion. Wir hoffen, sie hat dir bis hierher gefallen! Du kannst sie durch Kauf unseres Android Online-Kurs Gesamtpakets freischalten.

In unserem Android Online-Kurs Gesamtpaket befinden sich 43 große Lektionen, in denen wir dir schrittweise zeigen, wie voll funktionstüchtige Android Apps programmiert werden.

Diese Lektion ist Teil unseres Android Gesamtpakets. Insgesamt sind unsere Online-Kurse unterteilt in 13 frei zugängliche und 30 Premium-Lektionen.

Die Premium-Lektionen befinden sich in dem geschützten Bereich und sind nur für Käufer des Android Online-Kurs Gesamtpakets zugänglich.



Welche Inhalte befinden sich im Android Online-Kurs Gesamtpaket?

  • Das Gesamtpaket enthält alle Android Online-Kurse von ProgrammierenLernenHQ.
  • Im Paket enthalten ist unser großer Android Apps Programmieren Online-Kurs. Er ist unser Hauptkurs und besteht aus 35 großen Lektionen. Die Grundlagen der Android App Entwicklung praxisnah und verständlich zu lehren, ist das Hauptziel des Android Apps Programmieren Kurses.
  • Im Paket enthalten ist auch unser SQLite Datenbank App Programmieren Online-Kurs. Dieser Spezialkurs besteht aus 8 großen Lektionen und ist als weiterführender Kurs konzipiert worden. Der Kurs schließt an unseren Android Apps Programmieren Hauptkurs an und widmet sich dem speziellen Thema der SQLite Datenbanken.
  • Durch den Kauf erhältst du unbegrenzten Zugang zu allen Inhalten unseres Android Online-Kurs Gesamtpakets. Wir werden in Zukunft weitere Lektionen hinzufügen. Auch auf alle zukünftigen Lektionen erhältst du vollen Zugriff.

Wir hoffen, Dich bald als neuen Kursteilnehmer unserer Android Online-Kurse begrüßen zu dürfen!

Einmal kaufen und dadurch zeitlich unbegrenzten Zugriff auf alle Inhalte unseres Android Online-Kurs Gesamtpakets erhalten.



Hinweis: Der untere Quellcode ist Teil des geschützten Bereichs von ProgrammierenLernenHQ. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte.
Erfahre mehr über unsere Android Online-Kurse.

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

Im oberen Quellcode der Utility-Klasse wurden an mehreren Stellen Änderungen vorgenommen. Die eingefügten Zeilen sind grau markiert. Wir werden nun die durchgeführten Änderungen der Reihe nach besprechen.

In den Zeilen 5 bis 7 werden die Klassen JSONArray, JSONException und JSONObject mittels Import-Anweisungen innerhalb der Utility-Klasse sichtbar gemacht, so dass wir sie ohne den Namen ihres Packages verwenden können. Zusätzlich werden in den Zeilen 18 und 19 die Klassen ArrayList und List importiert.

In den Zeilen 90 bis 116 wird die neue Methode createQuotesFromJSONString() definiert. Sie besitzt einen Parameter vom Datentyp String, über den ihr die JSON-Daten übergeben werden, und liefert als Rückgabewert eine Liste mit Quote-Objekten zurück.

Die createQuotesFromJSONString() Methode

Wir werden nun die createQuotesFromJSONString() Methode genauer betrachten. Ihren Methodenrumpf haben wir bereits im theoretischen Teil kennengelernt, mit dem Unterschied, dass von der Methode nur die Zitatdaten verarbeitet werden und die Diagnosedaten unbeachtet bleiben.

Zur Übersichtlichkeit ist die Methode an dieser Stelle nochmals aufgeführt:

public static List<Quote> createQuotesFromJSONString(String jsonString) {

    List<Quote> receivedQuoteList = new ArrayList<>();

    try {
        JSONObject jsonObj = new JSONObject(jsonString);

        // Anforderen des JSON-Array Knotens mit den Quotes-Objekten
        JSONArray quotes = jsonObj.getJSONArray("quotes");

        // Durchlaufen des Quotes-Arrays und Auslesen der Daten jedes Quote-Objekts
        for (int i = 0; i < quotes.length(); i++) {
            JSONObject quote = quotes.getJSONObject(i);

            String imageId = quote.getString("id");
            String quoteAuthor = quote.getString("author");
            String quoteText = quote.getString("text");

            receivedQuoteList.add(new Quote(quoteText, quoteAuthor, imageId));
        }

    } catch (JSONException e) {
        Log.e(TAG, "JSONException: " + e.getMessage());
    }

    return receivedQuoteList;
}

In Zeile 3 wird die Variable receivedQuoteList deklariert und ihr ein ArrayList-Objekt zugewiesen. Die Variable ist vom Datentyp List, so dass wir später auch anstelle einer ArrayList eine LinkedList verwenden könnten. Die receivedQuoteList wird in sich die ausgelesenen Quote-Objekte aufnehmen.

In Zeile 6 lassen wir aus dem vom Webserver erhaltenen JSON-String ein JSONObjekt-Objekt erzeugen, welches die übertragenen Zitatdaten in sich enthält. Aus diesem JSONObjekt-Objekt lesen wir in Zeile 9 den JSONArray aus, der die Informationen über mehrere Zitate enthält.

Um an die Zitatinformationen zu gelangen, müssen wir den Array nun noch elementweise auslesen. Dies geschieht mit der for-Schleige in den Zeilen 12 bis 20. Mit jedem Schleifendurchlauf wird zuerst das aktuelle Array-Element ausgelesen und in der Variable quote vom Typ JSONObject gespeichert. Auf den Inhalt des JSONObjects quote wird mit Hilfe der getString() Methode und den entsprechenden Schlüsseln zugegriffen.

In den Zeilen 15, 16 und 17 werden auf diese Weise imageId, quoteAuthor und quoteText aus dem aktuellen JSONObject ausgelesen. Anschließend wird in Zeile 19 ein Quote-Objekt auf Basis dieser drei ausgelesenen Zitatinformationen erzeugt und der receivedQuoteList-Liste hinzugefügt.

Nachdem alle Array-Element ausgelesen wurden, wird mit der return-Anweisung in Zeile 26 die Methode verlassen und als Rückgabewert die mit Quote-Objekten gefüllte receivedQuoteList-Liste an den Aufrufer übergeben.

Mit diesen Quellcodezeilen haben wir die Parsing-Methode createQuotesFromJSONString() implementiert. Sie wird für uns die vom Webserver erhaltenen JSON-Daten auslesen und daraus eine Liste mit Quote-Objekten erstellen. Alles was wir ihr dazu übergeben müssen, ist der JSON-String mit den Zitatinformationen.

In Android Studio sollte der Inhalt der Utility.java Klassendatei nun wie folgt aussehen:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

In der oberen Abbildung ist die überarbeitete Utility.java Klassendatei dargestellt. Dem Quellcode wurden einige Import-Anweisungen und die createQuotesFromJSONString() Methode hinzugefügt. Es ist nur die hinzugefügte Methode aufgeklappt. Die beiden anderen Methoden wurden nicht verändert und sind daher zugeklappt.

Welche Bedeutung der jeweilige Code-Block besitzt, ist in der unteren Liste angegeben:

  1. A – Die benötigten Import-Anweisungen zum Sichtbarmachen der Klassen JSONArray, JSONException und JSONObject.
  2. B – Die benötigten Import-Anweisungen zum Sichtbarmachen der Klassen ArrayList und List.
  3. C – Die createQuotesFromJSONString() Methode zum Auslesen und Verarbeiten der Zitatdaten vom Webserver.

Da wir jetzt die createQuotesFromJSONString() Methode in der Hilfsklasse Utility erstellt haben, können wir als Nächstes den Parsing-Prozess, das Verarbeiten des JSON-Strings, von unserer App durchführen lassen. Dazu ist nur noch eine kleine Änderung an der MainActivity-Klasse vorzunehmen.

4. Starten des JSON-Parsing Prozesses in der MainActivity-Klasse

Wir haben nun die Parsing-Methode für JSON-Daten in der Utility-Klasse implementiert. Unsere Anwendung ist somit in der Lage die vom Webserver erhaltenen Zitatdaten auszulesen und daraus eine Liste mit Quote-Objekten zu erzeugen. Diesen Parsing-Prozess werden wir von dem asynchronen Task durchführen lassen, welcher durch die RequestQuotesTask-Klasse implementiert wird.

Und zwar werden wir in der doInBackground() Methode der Klasse RequestQuotesTask die Parsing-Methode createQuotesFromJSONString() aufrufen und ihr als Argument den JSON-String mit den Zitatdaten übergeben. Außerdem werden wir eine weitere Veränderung an der doInBackground() Methode vornehmen, indem wir nicht mehr benötigten Quellcode aus ihr entfernen.

Somit werden folgende Änderungen an der doInBackground() Methode vorgenommen:

  1. Löschen des nicht mehr benötigten Quellcodes in den Zeilen 7 bis 21.
  2. Hinzufügen der switch-Anweisung mit dem Aufruf der Parsing-Methode in den Zeilen 29 bis 37.
protected List<Quote> doInBackground(Integer... intParams) {

    int quotesCount = intParams[0];
    int parsingMethod = intParams[1];
    List<Quote> newQuoteList = new ArrayList<>();

    publishProgress("Bitte warten! " + quotesCount + " Zitate werden geladen.");

    for (int i = 0; i < quotesCount; i++) {
        // Mit Thread.sleep(350) simulieren wir eine Wartezeit von 350 ms
        // Dann fügen wir ein Quote-Objekt in die neue Zitat-Liste ein
        try {
            Thread.sleep(350);
            newQuoteList.add(new Quote(getString(R.string.sample_quote),
                    getString(R.string.sample_author), "goethe"));
        } catch (Exception e) {
            Log.e(INNER_TAG, "Thread-Error in inner class.", e);
        }
    }

    publishProgress(newQuoteList.size() + " Zitate wuden erfolgreich geladen.");

    String quotesString = Utility.requestQuotesFromServer(quotesCount, parsingMethod);

    if (quotesString != null) {
        Log.i(INNER_TAG, quotesString);

        // Hier lesen wir die empfangene Zeichenkette aus
        switch (parsingMethod) {
            case Utility.JSON_PARSING_METHOD:
                newQuoteList = Utility.createQuotesFromJSONString(quotesString);
                break;

            case Utility.XML_PARSING_METHOD:
                // Hier fügen wir später einen weiteren Methodenaufruf ein
                break;
        }

    } else {
        publishProgress("Daten konnten nicht geladen werden.");
    }

    return newQuoteList;
}

Um die oben beschriebenen Änderung am asynchronen Task vorzunehmen, überarbeiten wir nun die innere Klasse RequestQuotesTask der MainActivity-Klasse. Dazu öffnen wir die Klassendatei MainActivity.java im Editor von Android Studio mit einem Doppelklick auf ihren Dateinamen im Project Tool Window. Die Klassendatei befindet sich im Package-Ordner de.codeyourapp.zitate unseres Projekts.

In dem unten aufgeführten Quellcode der inneren Klasse RequestQuotesTask der MainActivity.java Datei sind die nun nicht mehr benötigten Quellcode-Zeilen bereits entfernt worden. Auch die switch-Anweisung mit dem Aufruf der createQuotesFromJSONString() Methode wurde bereits eingefügt:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

An oben aufgeführtem Quellcode der MainActivity-Klasse wurden zwei Änderungen an der inneren Klassen RequestQuotesTask vorgenommen. Und zwar wurden einige nicht mehr benötigte Quellcode-Zeilen gelöscht und eine switch-Anweisung innerhalb des if-Zweigs eingefügt.

Die switch-Anweisung wurde in den Zeilen 186 bis 194 eingefügt. In ihr wird überprüft, welche Parsing-Methode ausgeführt werden soll. Fall JSON-Daten ausgelesen werde sollen, wird in Zeile 188 die statische Methode createQuotesFromJSONString() über die Hilfsklasse Utility aufgerufen. Beim Aufruf wird ihr der vom Webserver erhaltene JSON-String als Argument übergeben.

Ihren Rückgabewert, eine Liste mit Quote-Objekten, wird in der Variable newQuoteList gespeichert. Diese Liste enthält die aus dem JSON-String ausgelesenen Zitatinformationen und wird nach Beenden der doInBackground() Methode automatisch an die onPostExecute() Methode des asynchronen Tasks übergeben. In der onPostExecute() Methode wird dann diese Quote-Liste als Datenquelle für den ListView unserer Android App eingesetzt.

Mit den Zeilen 191 bis 193 wurde auch schon der Aufruf einer weiteren Parsing-Methode vorbereitet. An dieser Stelle werden wir in der nächsten Lektion den Aufruf der XML-Parsing-Methode einfügen, so dass unsere Anwendung in der Lage sein wird, sowohl JSON– als auch XML-Daten zu verarbeiten.

Außer dem Löschen der nicht mehr benötigten Quellcode-Zeilen und dem Einfügen der switch-Anweisung müssen keine weiteren Änderungen an der doInBackground() Methode des asynchronen Tasks vorgenommen werden.

In Android Studio sollte die MainActivity.java Klassendatei nun wie folgt aussehen:

android_programmieren_lernen_blurry_sourcecode

Der obere Quellcode ist Teil des geschützten Bereichs. Durch Freischalten unserer Android Online-Kurse erhältst du Zugriff auf alle geschützten Inhalte. Klicke auf die Info-Box, um mehr zu erfahren.

In der oberen Abbildung ist die überarbeitete MainActivity.java Klassendatei dargestellt. Der Quellcode wurde nur in der doInBackground() Methode der inneren RequestQuotesTask-Klasse überarbeitet. Daher ist sie als einzige Methode aufgeklappt worden. Alle anderen Methoden bleiben geschlossen.

In der doInBackground() Methode wurde der asynchrone Task so überarbeitet, dass er nun auch das Parsing der JSON-Daten durchführt. Dies geschieht in der eingefügten switch-Anweisung, welche von einem blauen Rahmen (Markierung A) umschlossen ist. Zudem wurden einige nicht mehr benötigte Quellcode-Zeilen, die eine Wartezeit von einigen Sekunden simulierten, aus der doInBackground() Methode entfernt.

Führt der Benutzer nun die Swipe-Down Geste durch oder klickt auf den Action-Button in der App Bar, wird die refreshListView() Methode aufgerufen, von welcher der asynchrone Task gestartet wird. Der asynchrone Task startet daraufhin die HTTP-Anfrage und führt anschließend das Auslesen der vom Webserver erhaltenen JSON-Daten durch. Bei diesem Parsing-Prozess wird eine Quote-Liste erzeugt und dem ListView unserer Android App als neue Datenquelle zugewiesen.

Wie dies zur Laufzeit auf einem Android Gerät aussieht, werden wir im nächsten Abschnitt erfahren.

5. Ausführen und Testen unserer Android App

Wir werden nun unserer Android App auf einem Android Virtual Device im Emulator ausführen lassen. Unsere Anwendung hat in dieser Lektion einen großen Entwicklungssprung vollzogen. Sie kann nun echte online Daten von einem Webserver anfordern, intern auswerten und anschließend auf dem Display in dem ListView darstellen. Ob alles wie erwartet funktioniert, wollen wir nun überprüfen, indem wir mit einer Swipe-Down Geste den asynchronen Task starten.

Bevor wir unsere App auf dem Android Gerät ausführen lassen, müssen wir diese unbedingt vorher manuell von dem Android Virtual Device deinstallieren. Die benötigte Berechtigung (Internetzugriff) wird erst korrekt vom Android System erteilt, wenn vorher eine komplette Deinstallation unserer Android App stattgefunden hat. Danach kann die App neu auf das Android Gerät installiert und ausgeführt werden.

Unsere App starten wir dazu wie gewohnt über den Run > Run 'app' Menüeintrag, den wir über die obere Menüleiste erreichen.

Sobald unsere App auf dem AVD gestartet wurde, führen wir die Swipe-Down Geste durch oder klickt auf den Action-Button in der App Bar. Dadurch wird die refreshListView() Methode aufgerufen, von welcher der asynchrone Task gestartet wird. Der asynchrone Task stellt daraufhin sofort die HTTP-Anfrage an den Webserver, ohne dabei eine Ladezeit zu simulieren.

Wichtiger Hinweis: Falls die Fehlermeldung socket failed: EPERM (Operation not permitted) in der Logcat-Ausgabe erscheint, liegt das an einem Bug des Android Emulators in Verbindung mit Instant Run. Um diesen Fehler zu beheben, muss die Zitate-App zuerst manuell von dem AVD deinstalliert und anschließend mit Run > Run ‚app‘ wieder auf dem Gerät ausgeführt werden.

Die vom Server übermittelten JSON-Daten werden anschließend ausgelesen und für den ListView aufbereitet, indem eine Quote-Liste anhand der Zitatinformationen erzeugt wird. Sobald die Quote-Liste erstellt wurde, wird sie dem ListView als neue Datenquelle zugewiesen.

In der unteren Abbildung ist unsere Android App kurz nach Ausführen der Swipe-Down Geste zu sehen:

screenshot_json_parsing

Echte online Daten wurden vom asynchronen Task angefordert, ausgewertet und bereits im ListView ausgegeben.

Der asynchrone Task hat bereits die HTTP-Anfrage ausgeführt, die vom Webserver erhaltenen JSON-Daten ausgewertet und die Quote-Liste erstellt sowie diese dem ListView als neue Datenquelle zugewiesen. Auf dem Bildschirm werden die so übertragenen Zitate auch schon in Form von ListView-Einträgen ausgeben.

Zusammenfassung

In dieser Lektion haben wir die online Daten vom Webserver in unserer App weiterverarbeitet. Dazu haben wir die Zitatdaten aus der erhaltenen JSON-Zeichenkette ausgelesen und mit ihnen den ListView unserer Android App gefüllt.

Das Parsen der JSON-Daten haben wir vom asynchronen Task ausführen lassen, damit der UI-Thread von der Berechnung nicht blockiert wird. So bleibt die Benutzeroberfläche unserer App stets flüssig bedienbar, auch wenn die Bearbeitungszeit einmal mehrere Sekunden beträgt.

Im theoretischen Teil dieser Lektion haben wir das JSON-Format kennengelernt und erfahren mit welchen Werkzeugen JSON-Daten in Android effektiv ausgelesen und weiterverarbeitet werden können. Dabei sind wir auch auf die Datenstruktur unserer Zitatdaten genauer eingegangen.

Im praktischen Teil dieser Lektion haben wir zuerst zusätzliche Bilddateien, Autorenbilder von weiteren acht bedeutenden deutschen Lyrikern, unserem Android Studio Projekt hinzugefügt. Anschließend haben wir die Parsing-Methode für JSON-Daten in der Utility-Klasse implementiert.

Die createQuotesFromJSONString() Methode ist so implementiert, dass sie die Zitatdaten aus der vom Webserver übermittelte JSON-Zeichenkette ausliest und daraus eine Quotes-Liste erzeugt. Die so erstellte Liste wird anschließend an den Aufrufer zurückgeliefert und schließlich dem ListView unserer Android App als neue Datenquelle zugewiesen.

Abschließend haben wir unsere Android App im Emulator auf einem Android Virtual Device ausgeführt und geprüft, ob die übertragenen JSON-Zitatdaten korrekt ausgelesen, in eine Quotes-Liste umgewandelt und schließlich im ListView unserer App ausgegeben werden.

In der nächsten Lektion werden wir unsere Anwendung um eine weitere Parsing-Methode erweitern. Die neue Methode wird mit XML-Daten anstelle der JSON-Daten arbeiten. Auf diese Weise lernen wir ein weiteres wichtiges und populäres Datenaustauschformat näher kennen.

Weiterführende Literatur




Schreibe einen Kommentar

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