Dies ist eine Lektion unseres alten Android App programmieren Tutorials. Sie wird von uns nicht mehr aktuell gehalten und wurde durch unser neues Android Apps Programmieren Tutorial abgelöst, das immer aktuell gehalten wird.
Mit folgenden Link gelangt ihr zur aktuellen Version dieser Lektion: XML-Daten verarbeiten in Android.
Hier geht es zu unserem Android Tutorial mit den aktuellen Inhalten.
Da dieser Beitrag für einige Leser trotz fehlender Aktualität dennoch sehr hilfreich ist, haben wir ihn nicht gelöscht. Wenn ihr aber unser aktuelles Android Tutorial machen wollt, dann könnt ihr über den oberen Link direkt zu den neuen Inhalten gelangen.
In diesem Tutorial lernt ihr:
- Einführung in XML
- XML-Format der Online-Finanzdaten
- Aktiendaten aus dem XML-String auslesen (XML parsen in Android)
- Aktiendaten in der App anzeigen lassen
Ihr solltet auch lesen:
Im neunten Teil unseres großen Android™ Tutorials werden wir den String, der die XML-Aktiendaten enthält, auslesen.
Die, für uns momentan relevanten, XML-Finanzinformationen werden wir dabei in einem StringArray speichern und anschließend auf dem Android Gerät ausgeben.
In dem ersten Abschnitt dieses Tutorials werden wir das XML-Datenformat kurz vorstellen und auf die Besonderheiten der Extensible Markup Language (XML) eingehen.
Anschließend werden wir in Abschnitt zwei das XML-Format der Online-Aktiendaten analysieren und die, für uns relevanten, Finanzinformationen auswählen.
Im dritten Abschnitt erweitern wir dann unsere bisherige Android App um die Fähigkeit XML-Daten auszulesen. Als Datenquelle greifen wir auf die Online-Aktiendaten zurück, die in einem String abgelegt sind. Die ausgelesenen Finanzinformationen speichern wir danach in einem StringArray und geben sie anschließend auf dem Android Smartphone oder Tablet aus.
Nun wünschen wir euch viel Spaß bei dem neunten Teil unseres großen Android Tutorials. Los geht’s!
1. Einführung in XML (Extensible Markup Language)
Die Auszeichnungssprache XML wird zur Darstellung hierarchisch strukturierter Daten verwendet. Die Daten sind in Textform angegeben.
Die Extensible Markup Language (engl. „erweiterbare Auszeichnungssprache“, XML) ist für Menschen und Maschinen gleichermaßen verständlich und wird für den plattform- und implementationsunabhängigen Austausch von Daten zwischen Computersystemen eingesetzt, insbesondere über das Internet.
Eine XML-Datei besteht aus Textzeichen und ist auch von Menschen leicht lesbar. Binärdaten enthält ein XML-Dokument per Definition nicht.
Die Sprache XML wurde entwickelt, um mit ihr Daten beschreiben zu können. Im Gegensatz dazu steht die Sprache HTML, welche entwickelt wurde, um Daten darzustellen.
Beispiel eines XML-Dokuments
Der folgende XML-Code beschreibt das Inventar eines Buchladens:
<?xml version="1.0" encoding="UTF-8"?> <Buchladen> <Buch Kategorie="Java"> <Titel Sprache="de">Handbuch der Java Programmierung</Titel> <Autor>Guido Krüger / Heiko Hansen</Autor> <Jahr>2012</Jahr> <Preis>49.80</Preis> </Buch> <Buch Kategorie="Android"> <Titel Sprache="de">Spieleprogrammierung mit Android Studio</Titel> <Autor>Uwe Post</Autor> <Jahr>2014</Jahr> <Preis>34.90</Preis> </Buch> <Buch Kategorie="Android"> <Titel Sprache="de">Android - Der schnelle und einfache Einstieg</Titel> <Autor>Dirk Louis / Peter Müller</Autor> <Jahr>2014</Jahr> <Preis>29.99</Preis> </Buch> </Buchladen>
Die erste Zeile ist die XML Deklaration. Sie definiert die XML-Version, hier Version 1.0.
In der nächsten Zeile wird das Wurzelelement Buchladen
des XML-Dokuments beschrieben. Jedes XML-Dokument muss genau ein Wurzelelement (root element) besitzen. Die Elemente eines XML-Dokuments formen eine Baumstruktur. Der Dokumentenbaum beginnt mit der Wurzel, dem Wurzelelement, und führt zu den Blättern, den Kinderelementen (child elements).
Das Wurzelelement liegt in der obersten Ebene. Unterhalb dieser Ebene können beliebig viele weitere Kinderelemente verschachtelt werden. Das Wurzelelement Buchladen
besitzt die drei Buch
-Kinderelemente. Diese drei Kinderelemente sind Geschwisterelemente.
Jedes dieser drei Geschwisterelemente besitzt das Attribut Kategorie
. Der Attribut-Wert wird in Anführungszeichen nach dem =
angegeben. Elemente können beliebig viele Attribute besitzen.
Jedes Buch
-Kinderelement besitzt vier eigene Kinderelemente Titel
, Autor
, Jahr
und Preis
. Zwischen dem Start- und End-Tag eines Elements wird der Elementinhalt als reiner Text angegeben.
Das folgende Diagramm repräsentiert ein Buch aus dem oberen Beispiel XML-Dokument:
In dem oberen Diagramm sind auch die Beziehungen der verschiedenen Elemente untereinander dargestellt. So ist der Buchladen das Vaterelement des Buchs und das Buch selbst ein Kindelement des Buchladens. Der Buchladen ist auch das Wurzelelement des XML-Dokuments.
Das Buch besitzt vier Kindelemente (Titel, Autor, Jahr und Preis) die untereinander Geschwisterelemente sind. Das Buch-Element besitzt das Attribut „Kategorie“, das den Wert Android enthält.
Weitere Informationen und ein sehr schönes Tutorial über XML könnt ihr bei w3schools.com finden: http://www.w3schools.com/xml/default.asp.
2. XML-Format der Online-Finanzdaten
Da wir nun die Grundlagen von XML kennen, können wir einen genaueren Blick auf das XML-Format der Online-Finanzdaten, die wir von unserem Web-Server erhalten, werfen.
Der Server liefert die Online-Aktiendaten im XML-Format. Bisher speichert unsere Android App die empfangenen Daten in einem einfachen String ab.
Der XML-String muss von uns ausgelesen werden (parsen), dazu ist es erforderlich den Aufbau des XML-Formats der Finanzdaten zu kennen.
Mit folgender Anfrage lassen wir von unserem Server simulierte Aktiendaten für die Unternehmen Daimler (DAI.DE) und BMW (BMW.DE) erzeugen:
Die Online-Aktiendaten erhalten wir in folgendem XML-Format zurück:
<query> <diagnostics> <symbols>DAI.DE,BMW.DE</symbols> <created>2017-11-15 20:44:25</created> </diagnostics> <results> <row> <symbol>DAI.DE</symbol> <name>DAI</name> <currency>EUR</currency> <exchange>GER</exchange> <price>44.73</price> <date>11/15/2017</date> <time>8:44pm</time> <change>0.281799</change> <percent>0.63%</percent> <open>44.8708995</open> <high>45.1245186</high> <low>44.3918412</low> <volume>7572249</volume> </row> <row> <symbol>BMW.DE</symbol> <name>BMW</name> <currency>EUR</currency> <exchange>GER</exchange> <price>39.72</price> <date>11/15/2017</date> <time>8:44pm</time> <change>0.6951</change> <percent>1.75%</percent> <open>40.06755</open> <high>40.69314</high> <low>38.88588</low> <volume>7014513</volume> </row> </results> </query>
Als Nächstes werden wir die Struktur der XML-Aktiendaten analysieren. Das Wurzelelement des XML-Dokuments ist query
. Es besitzt die beiden Kindelemente (child elements):
diagnostics
results
Für unsere Android Anwendung ist besonders das Element results
interessant. Es enthält alle Informationen über die angefragten Finanzinstrumente, die Daten sind in den Geschwisterelementen mit dem Namen row
angegeben. Für jedes angefragte Finanzinstrument (Aktie, Indize, …) ist ein entsprechendes row
-Element angelegt worden.
Jedes row
-Elemente besitzt die folgenden 13 Kindelemente:
symbol
name
currency
exchange
price
date
time
change
percent
open
high
low
volume
Davon sind momentan die Elemente symbol
, name
, currency
, price
und percent
für unsere AktieHQ App von großer Bedeutung, aber auch die anderen Elemente enthalten nützliche Finanzinformationen für spätere Entwicklungsstufen unsere Anwendung.
In dem folgenden Diagramm ist das XML-Format der gelieferten Online-Finanzdaten dargestellt:
Für unsere Android Anwendung ist es wichtig die hierarchische Struktur der XML-Aktiendaten zu kennen. Besonders welche Elemente welche Finanzinformationen enthalten. Im nächsten Abschnitt werden wir den XML-String parsen (auslesen) und die erhaltenen Finanzinformationen auf dem Display ausgeben.
3. Online-Aktiendaten aus dem XML-String auslesen
Um XML-Dokumente in Android zu verarbeiten, sind verschiedene Standards verfügbar. Ein sehr oft verwendeter Standard ist JAXP (Java API for XML Processing).
Von JAXP werden drei verschiedene Programmierschnittstellen zur Verfügung gestellt, die XML-Dokumente interpretieren können:
Wir werden unsere XML-Finanzdaten mit der DOM-Schnittstelle verarbeiten. Der DOM-Standard lädt beim Parsen das XML-Dokument in den Hauptspeicher und stellt es dort in Form eines Objektbaums zur Verfügung.
Die Erstellung eines solchen DOM-Objektbaums aus einem XML-Dokument lässt sich mit wenigen Zeilen Code bewerkstelligen. Daher ist DOM die optimale Methode für das Parsen von XML-Daten für unsere Android Anwendung.
Jedoch besitzt es auch einen großen Nachteil: das komplette XML-Dokument liegt im Arbeitsspeicher. Dies ist bei sehr großen XML-Dateien ein Performance-Problem. In unserem Fall jedoch nicht, da unser XML-Aktiendaten String nur von sehr geringer Größe ist.
3.1 Importieren der benötigten Klassen, Interfaces und Exceptions
Um unsere XML-Aktiendaten auszulesen, werden wir den XML-Parser des Packages javax.xml.parser
verwenden. Der XML-Parser zerlegt den XML-Eingabestrom in seine grammatikalischen Bestandteile.
Um ihn nutzen zu können, müssen wir die folgenden zwei Klassen und eine Exception importieren:
AktienlisteFragment.java
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException;
Der XML-Parser liest unseren XML-String ein und erzeugt daraus einen Objektbaum. Damit wir den Objektbaum verwenden können, müssen wir noch einige Interfaces des Packages org.w3c.dom
importieren. Unter anderem liegt darin das Interface Document, welches den eingelesenen Objektbaum repräsentiert.
Diese folgenden vier Interfaces müssen wir importieren:
AktienlisteFragment.java
import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList;
Als vorletzten Import laden wir die Klasse InputSource aus dem Package org.xml.sax
, der unseren XML-String in eine InputSource einlesen und umwandeln wird. Diese InputSource werden wir dann an den XML-Parser übergeben.
Wir müssen daher die folgende Klasse und Exception importieren:
AktienlisteFragment.java
import org.xml.sax.InputSource; import org.xml.sax.SAXException;
Als letzten Import laden wir die StringReader-Klasse:
AktienlisteFragment.java
import java.io.StringReader;
Nachdem wir die notwendigen Importanweisungen in unser Android Projekt in die Klasse AktienlisteFragment eingefügt haben, kommen wir im nächsten Teilabschnitt zu dem eigentlichen Quellcode, durch den die XML-Aktiendaten ausgelesen (geparst) werden.
3.2 Auslesen der Online-Aktiendaten mit Hilfe eines XML-Parsers
Die XML-Aktiendaten lesen wir mit Hilfe der neuen Methode leseXmlAktiendatenAus(String xmlString) aus, der wir den XML-String mit den Online-Aktiendaten übergeben. Die Methode rufen wir am Ende des doInBackground-Tasks auf, dazu später mehr.
Die neue Methode leseXmlAktiendatenAus muss in der inneren Klasse HoleDatenTask der Klasse AktienlisteFragment definiert werden:
AktienlisteFragment.java
private String[] leseXmlAktiendatenAus(String xmlString) { Document doc; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(); is.setCharacterStream(new StringReader(xmlString)); doc = db.parse(is); } catch (ParserConfigurationException e) { Log.e(LOG_TAG,"Error: " + e.getMessage()); return null; } catch (SAXException e) { Log.e(LOG_TAG,"Error: " + e.getMessage()); return null; } catch (IOException e) { Log.e(LOG_TAG,"Error: " + e.getMessage()); return null; } Element xmlAktiendaten = doc.getDocumentElement(); NodeList aktienListe = xmlAktiendaten.getElementsByTagName("row"); int anzahlAktien = aktienListe.getLength(); int anzahlAktienParameter = aktienListe.item(0).getChildNodes().getLength(); String[] ausgabeArray = new String[anzahlAktien]; String[][] alleAktienDatenArray = new String[anzahlAktien][anzahlAktienParameter]; Node aktienParameter; String aktienParameterWert; for( int i=0; i<anzahlAktien; i++ ) { NodeList aktienParameterListe = aktienListe.item(i).getChildNodes(); for (int j=0; j<anzahlAktienParameter; j++) { aktienParameter = aktienParameterListe.item(j); aktienParameterWert = aktienParameter.getFirstChild().getNodeValue(); alleAktienDatenArray[i][j] = aktienParameterWert; } ausgabeArray[i] = alleAktienDatenArray[i][0]; // symbol ausgabeArray[i] += ": " + alleAktienDatenArray[i][4]; // price ausgabeArray[i] += " " + alleAktienDatenArray[i][2]; // currency ausgabeArray[i] += " (" + alleAktienDatenArray[i][8] + ")"; // percent ausgabeArray[i] += " - [" + alleAktienDatenArray[i][1] + "]"; // name Log.v(LOG_TAG,"XML Output:" + ausgabeArray[i]); } return ausgabeArray; }
Die Methode leseXmlAktiendatenAus untergliedert sich in zwei Teile. Der erste Teil von Zeile 3 bis 21 ist für das Parsen des XML-Strings und Erzeugen des Objektbaums mit den Aktiendaten zuständig.
Der zweite Teil von Zeile 22 bis 48 greift auf den Objektbaum zu und liest aus ihm die Aktiendaten aus. Wir verwenden dafür die Methoden getElementsByTagName und getChildNodes, mit denen wir sehr komfortabel auf die gewünschten XML-Elemente und Werte zugreifen können.
Mit den verschachtelten for-Schleifen lesen wir alle Aktiendaten unserer Aktienliste aus. Die ausgelesenen Werte speichern wir in dem zweidimensionalen Array alleAktienDatenArray
ab und bauen damit den String-Array ausgabeArray
zusammen.
Am Ende der Methode geben wir die ausgelesenen Finanzinformationen zurück.
3.3 Aufrufen der Methode leseXmlAktiendatenAus
Damit die XML-Aktiendaten ausgelesen werden, müssen wir noch die Methode leseXmlAktiendatenAus, von einer Stelle in unserer Anwendung aus, aufrufen. Der richtige Ort dafür ist kurz vor Ende der doInBackground-Methode unseres asynchronen Tasks.
Wir führen den Methodenaufruf bei der return-Anweisung aus und geben somit den erhaltenen String-Array sofort weiter.
AktienlisteFragment.java
protected String[] doInBackground(String... strings) { . . . return leseXmlAktiendatenAus(aktiendatenXmlString); }
Der obere Code enthält nur die return-Anweisung mit dem Methodenaufruf. Der restliche Programmcode (durch die drei Punkte dargestellt) ist hier nicht angegeben, da er nicht verändert wurde.
Der übergebene aktiendatenXmlString enthält die von unserem Web-Server erhaltenen simulierten Aktiendaten im XML-Format. Die Methode leseXmlAktiendatenAus liest diesen XML-String aus und speichert die relevanten Finanzinformationen in einem String-Array ab. Der String-Array wird dann an die aufrufende Methode zurückgegeben.
3.4 Ausgelesene XML-Aktiendaten in ArrayAdapter einfügen
Die Methode doInBackground gibt den String-Array, der die relevanten Finanzinformationen enthält, mittels return-Anweisung weiter. Dadurch steht der String-Array jetzt als Ergebnis des asynchronen Tasks zur Verfügung und wird der Methode onPostExecute als Parameter automatisch übergeben.
Die Methode onPostExecute bleibt unverändert. Zur Übersicht ist sie hier dennoch aufgeführt:
AktienlisteFragment.java
protected void onPostExecute(String[] strings) { // Wir löschen den Inhalt des ArrayAdapters und fügen den neuen Inhalt ein // Der neue Inhalt ist der Rückgabewert von doInBackground(String...) also // der String-Array gefüllt mit Beispieldaten if (strings != null) { mAktienlisteAdapter.clear(); for (String aktienString : strings) { mAktienlisteAdapter.add(aktienString); } } // Hintergrundberechnungen sind jetzt beendet, darüber informieren wir den Benutzer Toast.makeText(getActivity(), "Aktiendaten vollständig geladen!", Toast.LENGTH_SHORT).show(); }
Die Methode onPostExecute wird am Ende des asynchronen Task automatisch aufgerufen. In ihr füllen wir den ArrayAdapter mit den ausgelesenen Online-Aktiendaten, dessen Inhalt in dem ListView eingefügt und anschließend auf unserem Android Gerät ausgegeben wird.
Da die Klasse AktienlisteFragment unserer Android App an verschiedenen Stellen verändert werden musste, kann es leicht zu Fehlern und Missverständnissen kommen. Um dies auszuschließen, solltet ihr euren Code zur Kontrolle mit der gesamten Klassendatei AktienlisteFragment.java
vergleichen.
4. Testen unserer Android App und Anzeigen der aktuellen Online-Aktiendaten
Dies ist ein großer Moment in der Entwicklung unserer AktieHQ App. Wir lassen das erste Mal simulierte Online-Aktiendaten auf unserem Android Smartphone oder Tablet anzeigen. Damit ist unsere Android App erstmals sinnvoll nutzbar und versorgt uns mit dem aktuellen Finanzdaten.
Damit wir unsere App auf dem Smartphone oder Tablet starten können, müssen alle Schritte von Teil 3 des Android Tutorials befolgt worden sein.
Zuerst schließen wir unser Android Gerät an den PC an und stellen eine Verbindung über die ADB (Android Debug Bridge) her. Danach klicken wir auf das Run 'app'
-Symbol. Unser Android Projekt wird dadurch neu erstellt und auf dem angeschlossenen Gerät ausgeführt.
Das Run 'app'
-Symbol befindet sich in der oberen Menüleiste, siehe folgende Abbildung:
Nach einigen Momenten öffnet sich der Select Deployment Target
-Dialog. In ihm nehmen wir die folgenden Einstellungen vor:
- Das angeschlossene Android Gerät unter
Connected Devices
auswählen. - Mit einem Klick auf den
OK
-Button die Installation unserer App auf das Gerät starten.
Der Dialog schließt sich und unsere Android App wird auf das angeschlossene Gerät übertragen und installiert. Die Installation dauert nur einen kurzen Augenblick und verläuft fast unbemerkt im Hintergrund. Danach wird unsere App automatisch gestartet.
4.1 Aktuelle Aktiendaten mit unserer App abfragen und anzeigen
Zu Beginn sehen wir die alten Beipiel-Aktiendaten (mock data) in unserem ListView. Um die simulierten Online-Finanzdaten bei unserem Web-Server abzufragen, müssen wir auf den Aktualisieren
-Button im Overflow Menu klicken.
Die folgende Abbildung zeigt, wie unsere Android App die Aktiendaten über das Internet abfragt:
Die Online-Aktiendaten werden als Strings in dem ListView angezeigt. Wir geben für jeden Eintrag das ausgelesene Symbol, den Kurswert mit Währung, die Änderung zum Vortag in Prozent sowie den Namen des Finanzinstruments aus. Für den Moment sind diese Angaben völlig ausreichend.
Möchten wir weitere Finanzinformationen ausgeben, müssen wir diese aus dem XML-String auslesen und gesondert auf dem Android Gerät darstellen. Hierfür empfiehlt sich die Verwendung von Grafiken, wodurch die Darstellung aufgelockert wird und unsere Android Anwendung benutzerfreundlicher ist.
Was auf dem oberen Bild nicht zu sehen ist, sind die beiden anderen Kurzmitteilungen (Toasts), die über den aktuellen Status der Aktiendatenanfrage informieren. Im Bild ist nur der letzte Toast dargestellt: „Aktiendaten vollständig geladen!“.
4.2 Video – Laden von Online-Aktiendaten mit unserer Android App
Nun möchten wir unserer Anwendung auch einmal beim Holen der Online-Aktiendaten über die Schulter schauen. Dazu haben wir das folgende kurze Video erstellt, in dem die Funktion unserer App vorgestellt wird:
Zuerst sieht man die App im Startzustand. Mit einem Klick auf den Aktualisieren
-Button wird der asynchrone Task HoleDatenTask im Hintergrund gestartet.
Der asynchrone Task fragt zuerst die Online-Aktiendaten bei unserem Web-Server im XML-Format ab und liest die empfangenen XML-Daten anschließend aus. Dabei werden die relevanten Finanzinformationen (Symbol, Preis, Währung, Änderung in Prozent und Name) in den ListView eingefügt und auf dem Android Gerät angezeigt.
Danach wird der asynchrone Task beendet und unsere Android App hat die Abfrage der Online-Aktiendaten für die Finanzinstrumente BMW.DE, DAI.DE und ^GDAXI beendet.
Zusammenfassung
In diesem Teil des großen Android Tutorials haben wir das Auslesen von XML-Daten kennengelernt. Die Sprache XML (Extensible Markup Language) wurde zu Beginn kurz vorgestellt und dabei auf ihre hierarchische Struktur eingegangen.
Anschließend haben wir das Format der simulierten XML-Aktiendaten analysiert und die relevanten Finanzinformationen für unsere Android App festgelegt.
Danach erweiterten wir unsere Anwendung um eine XML-Auslese-Funktion. Mit der neu definierten Methode leseXmlAktiendatenAus ist unsere App in der Lage XML-Strings auszulesen und auf bestimmte Elemente zuzugreifen. Momentan lesen wir nur fünf Parameter aus den Online-Aktiendaten aus. Es bestehen also noch viele Möglichkeiten unsere App weiter zu verbessern und nützlicher zu machen.
Abschließend haben wir die AktieHQ App auf dem Android Gerät installiert und ausgeführt. Das Video weiter oben zeigt den aktuellen Entwicklungsstand unserer Anwendung.