android sqlite_wowomnom_Fotolia_85154667

Android SQLite Datenbank Tutorial – Teil 5: Mit der SQLite App auf Benutzereingaben reagieren


In der fünften Lektion unseres mehrteiligen Android SQLite Tutorials werden wir unserer Android App Funktionalität hinzufügen. Wir werden auf Benutzereingaben reagieren und erfassen welche Werte in die EditText-Felder eingetragen sind.

Die grafische Benutzeroberfläche steuern wir von der MainActivity aus. Daher wird sie auch die einzige Klasse sein, deren Quellcode wir in dieser Lektion überarbeiten.

Doch bevor wir Änderungen an der Projektdatei vornehmen, werden wir uns mit dem Lebenszyklus von Activities und Fragmenten näher beschäftigen.

Der Android Lifecycle ist für die Arbeit mit Datenbanken sehr wichtig, da man genau wissen muss, wann die Verbindung zur SQLite Datenbank geöffnet bzw. geschlossen werden sollte.

Danach beschäftigen wir uns mit den Fragen:

  • Wie liest man ein EditText-Feld in Android aus?
  • Wie erkennt man, dass ein Button angeklickt wurde?

Im dritten Abschnitt werden wir dann das Gelernte in unserer SQLite App anwenden und die MainActivity-Klasse umstrukturieren und erweitern. Wir werden die Life Cycle Callback-Methoden onResume() und onCreate() überschreiben, um in ihnen die Verbindung zur Datenbank korrekt zu verwalten.

Weiterhin werden wir einen OnClickListener für den Add-Button registrieren und so auf Benutzereingaben reagieren. Durch einen Klick auf den Button sollen die in die EditText-Felder eingetragenen Werte in die Tabelle der SQLite Datenbank geschrieben werden.

Abschließend werden wir unsere SQLite App ausführen und testen, dabei werden wir erstmals echte Werte in die Datenbank über die grafische Benutzeroberfläche eintragen.

Nun wünschen wir euch viel Spaß bei Teil 5 unseres Android SQLite Datenbank Tutorials. Los geht’s!

1. Der Lebenszyklus einer Activity in Android

Eine Android App besteht meist aus mehreren Activities, die lose miteinander verbunden sind. Wenn eine neue Activity gestartet wird, ändert die aktuelle Activity ihren Zustand und wird gestoppt.

Die neu gestartete Activity erhält den Fokus und wird ganz oben auf dem Backstack abgelegt. Die gestoppte Activity befindet sich direkt darunter.

Der Zustand der gestoppten Aktivität bleibt im Android System erhalten, da die gestoppte Activity bereits auf dem Back Stack abgelegt war und nur eine Position nach hinten verschoben wurde.

Drückt der Benutzer jetzt den Back-Button, wird die gestartete Aktivität vom Back Stack entfernt und zerstört. Zeitgleich wird die vorherige, gestoppte Aktivität wieder fortgesetzt (restarted) und erhält den Fokus. Der Back Stack arbeitet nach dem Last in, First out-Prinzip.

Wenn eine Activity gestoppt wird, weil eine neue Activity startet, wird sie über die Zustandsänderung durch die Lifecycle-Callbacks informiert. In Android sind mehrere Callback-Methoden implementiert, die bei einer Zustandsänderung der Aktivität aufgerufen werden.

Jede Callback-Methode bietet die Gelegenheit bestimmte, notwendige Arbeiten auszuführen, bevor die Zustandsänderung in Kraft tritt. Für uns sind die beiden Callback-Methoden onResume() und onPause() für die Verwaltung der SQLite Datenbankverbindung besonders wichtig.

Im Folgenden werden wir den Android Lifecycle mit seinen Callback-Methoden vorstellen und anschließend die für unsere SQLite App relevanten Lifecycle-Callbacks besprechen.

1.1 Der Android Lifecycle von Activities und Fragmenten

Neben Activities durchlaufen auch Fragmente einen wohldefinierten Lebenszyklus. Wir werden nun kurz beide Zyklen vorstellen und dabei besonders auf den Activity Lifecycle eingehen. Falls ihr tiefer in die Materie eintauchen möchtet, solltet ihr den theoretischen Teil des folgenden Beitrags in Ruhe lesen: Der Activity und Fragment Lifecycle in Android.

Wenn eine Activity ihren aktuellen Zustand verlässt und einen neuen Zustand betritt, wird sie über verschiedene Callback-Methoden über die Zustandsänderung informiert. Alle Callback-Methoden können überschrieben werden, wodurch entsprechend auf die Zustandsänderung reagiert werden kann.

In Android sind die folgenden Lifecycle-Callbacks für Activities definiert:

  • onCreate(Bundle savedInstanceState) – Die Activity wird erstellt. Hier beginnt der Lebenszyklus.
  • onStart() – Die Activity ist kurz davor sichtbar zu werden.
  • onResume() – Die Activity ist sichtbar geworden und hat den Benutzer-Fokus.
  • onPause() – Eine andere Activity erhält den Fokus. Diese Activity wird pausiert.
  • onStop() – Die Activity ist nicht mehr sichtbar und wird nun gestoppt.
  • onRestart() – Die Activity wird neu gestartet. Als Nächstes wird onStart() aufgerufen.
  • onDestroy() – Die Activity wird zerstört werden. Hier endet der Lebenszyklus.
  • onSaveInstanceState(Bundle outState) – Die Activity wird in den nächsten Momenten gestoppt. Jetzt kann der aktuelle Zustand als Sammlung von Key-Value Paaren gespeichert werden.
  • onRestoreInstanceState(Bundle savedInstanceState) – Die Activity wird wieder hergestellt, nachdem sie aufgrund von Speichermangel zerstört wurde. Dieser Callback wird nur aufgerufen, wenn das Bundle nicht null ist. Der Aufruf erfolgt unmittelbar nach onStart().

Die folgende Abbildung verdeutlicht in welcher Reihenfolge die Lifecycle-Callbacks aufgerufen werden:

android activity lifecycle

Die Callback-Methoden des Activity Lifecycle in Android

Die Rechtecke repräsentieren die Callback-Methoden, die von euch implementiert werden können, um notwendige Operationen bei Zustandsänderungen durchzuführen.

Für unsere SQLite App sind die folgenden beiden Callback-Methoden relevant:

  • onResume() – Die Activity ist sichtbar geworden und hat den Benutzer-Fokus. Hier werden wir die Verbindung zur SQLite Datenbank herstellen.
  • onPause() – Die Activity wird pausiert. Hier werden wir die Verbindung zur SQLite Datenbank trennen. Diese Callback-Methode ist die letzte garantiert aufgrufene Methode bevor eine Activity zerstört werden kann. Normalerweise werden die nachfolgenden Callbacks auch noch ausgeführt. Dies kann aber nicht garantiert werden, bspw. bei akutem Speichermangel.

Somit wissen wir nun welche Lifecycle-Callbacks unserer MainActivity wir überschreiben werden und auch warum wir dies tun.

Zur Vollständigkeit gehen wir nun auch kurz auf den Lebenszyklus von Fragmenten in Android ein. Für unsere App ist dies nicht relevant, da sie nur über eine Activity und keine Fragmente verfügt.

android fragment lifecycle

Die Callback-Methoden des Fragment Lifecycles in Android

Der Quellcode eines Fragments ist dem einer Activity sehr ähnlich. Ein Fragment besitzt die gleichen Callback-Methoden wie eine Activity (bspw. onCreate(), onStart(), onPause(), onStop() und onDestroy()).

Zusätzlich verfügt ein Fragment über einige weitere Callback-Methoden, wie onAttach(), onCreateView(), onActivityCreated(), onDestroyView() und onDetach().

Da es so viele Gemeinsamkeiten zwischen Activities und Fragmenten gibt, kann in vielen Fällen Code von der Callback-Methode der Activity in die entsprechende Callback-Methode des Fragments umgelagert werden, wenn eine Android App auf Fragmente umgestellt werden soll.

Der Hauptunterschied im Lebenszyklus von Activities und Fragmenten ist die Art und Weise wie sie jeweils in dem entsprechenden Back Stack angelegt werden.

Eine gestoppte Activity wird auf den Activities Back Stack gelegt, welcher vom Android System verwaltet wird. Der User kann mit dem Back-Button zurück in die gestoppte Activity navigieren.

Ein Fragment wird jedoch auf einen speziellen Back Stack gelegt, welcher von der übergeordneten Activity verwaltet wird. Dies ist aber nur der Fall, wenn es mit dem Aufruf von addToBackStack() beim Entfernen des Fragments explizit so angewiesen wurde.

Auf der rechten Seite ist der Fragment Lifecycle in Android dargestellt. Wie zu erkennen ist, sind die meisten Callback-Methoden auch im Activity Lebenszyklus vorhanden.

Soviel zu dem spannenden Thema Android Lifecycle.

Kommen wir nun zu den relevanten Callbacks-Methoden onResume() und onPause() unserer MainActivity-Klasse zurück, auf die wir im nächsten Unterabschnitt genauer eingehen werden.

1.2 Welche Lifecycle Callbacks sind für unsere SQLite App relevant

Es gibt viele Gründe Lifecycle-Callbacks in Android Apps zu verwenden. Oft werden die Callbacks genutzt um den Zustand der Membervariablen zu speichern und diesen später beim Erzeugen der Activity wieder herzustellen.

Auch das Abtasten von Sensordaten wird mit Hilfe der Callbacks gezielt aktiviert und deaktiviert, um den Akku zu schonen.

Wir werden die Lifecycle-Callbacks verwenden, um die Verbindung zur SQLite Datenbank korrekt zu verwalten.

Wir benötigen eine offene Verbindung nur, wenn unsere MainActivity den Benutzer-Fokus besitzt. Also sich in dem Resumed-Zustand befindet.

Eine Activity kann in den folgenden drei Zuständen existieren:

  • Resumed – Die Activity ist im Bildschirmvordergrund und besitzt den Benutzer-Fokus.
  • Paused – Eine andere Activity ist im Bildschirmvordergrund und besitzt den Benutzer-Fokus, verdeckt jedoch die überlagerte Activity nicht komplett. Ein Settings-Dialog bspw. verdeckt die Activity nur teilweise. Im Paused-Zustand ist eine Activity vollständig intakt (alive). Das Activity-Objekt wird im Speicher gehalten und alle Zustands- und Memberinformationen bleiben erhalten. Die pausierte Activity kann jedoch vom Android System in Situationen mit extrem niedrigem Speicher zerstört (killed) werden.
  • Stopped – Die Activity wird von einer anderen Activity vollständig verdeckt und befindet sich nun um Bildschirmhintergrund. Auch eine gestoppte Activity ist intakt. Das Activity-Objekt wird im Speicher gehalten und alle Zustands- und Memberinformationen bleiben erhalten. Die Activity ist jedoch nicht mehr dem Window Manager zugewiesen. In Situationen mit extrem wenig verfügbarem Speicher kann eine gestoppte Activity vom Android System zerstört werden.

Eine pausierte oder gestoppte Activity kann jederzeit vom Android System zerstört werden. Dies geschieht entweder durch Aufrufen der finish()-Methode oder durch direktes Beenden ihres Prozesses. Wird eine zerstörte Activity wieder geöffnet, muss sie komplett neu erstellt werden.

Sobald die MainActivity den Benutzer-Fokus verliert, werden wir die Verbindung zur SQLite Datenbank schließen. Die Verbindung bleibt so lange geschlossen, bis die Activity den Benutzer-Fokus wieder zurück erhält.

Die Operationen für das Öffnen und Schließen der Datenbankverbindung müssen daher in den folgenden Callback-Methoden stattfinden:

onResume()
Wird aufgerufen, kurz bevor die Activity mit dem Benutzer interagiert. Zu diesem Zeitpunkt ist die Activity ganz oben auf dem Activity Stack und empfängt die Benutzereingaben. In ihr werden wir die Verbindung zur SQLite Datenbank herstellen. Das Android System kann den App-Prozess nach dieser Methode nicht beenden. Der Methode folgt immer die onPause() Methode.


onPause()
Wird aufgerufen, kurz bevor das System eine andere Activity startet. In ihr sollten vorgenommene Änderungen gespeichert und Animationen beendet werden. Diese Vorhaben sollten unbedingt sehr schnell ausführbar sein, da die nächste Activity erst danach fortgesetzt wird. In dieser Methode werden wir die Verbindung zur SQLite Datenbank trennen. Nach dieser Methode kann das Android System den App-Prozess direkt beenden, sollte dies aufgrund von Speichermangel erforderlich sein. Der Methode folgt die onResume() Methode, wenn die Activity wieder in den Vordergrund rückt bzw. die onStop() Methode, wenn die Activity verdeckt wird.


Jetzt wissen wir welche Callback-Methoden wir für das Verwalten der SQLite Datenbankverbindung verwenden werden. In Abschnitt 3 werden wir Anweisungen aus der onCreate() Methode in die beiden Callback-Methoden auslagern.

Doch bevor wir dies tun werden, möchten wir noch kurz besprechen wie Benutzereingaben in Android erfasst und verarbeitet werden.

2. Benutzereingaben erfassen und auf Klicks reagieren

Mit unserer Einkaufslisten-App sollen die User in der Lage sein über die beiden EditText-Felder Eingaben vorzunehmen und diese mit einem Klick auf den Add-Button in die SQLite Datenbank eintragen zu lassen.

Um dies zu realisieren, müssen wir zwei neu Funktionen unserer App hinzufügen. Unsere SQLite App muss das Klicken auf den Add-Button erkennen und die in den EditText-Feldern eingetragenen Werte auslesen können.

Ob ein Button geklickt wurde, wird mit einem OnClickListener überprüft.

Das Auslesen der EditText-Felder wird mit Hilfe der Ressourcen-Datei R von Android bewerkstelligt. Über welche wir die entsprechenden Widget-Objekte finden und deren Inhalte anschließend auslesen können.

2.1 Wie liest man eine EditText-Feld in Android aus?

Das Auslesen eines EditText-Feldes ist sehr einfach. Wir müssen dazu nur seine ID kennen, über die wir an das zugehörige EditText-Objekt gelangen. Der Inhalt des Feldes kann mit der getText() Methode ausgelesen werden, die auf dem entsprechenden EditText-Objekt aufgerufen wird.

Der folgende Quellcode zeigt wie ein EditText-Feld ausgelesen und dessen Inhalt weiterverarbeitet wird:


Mit der Anweisung in Zeile 3 suchen wir nach der Instanz des EditText-Feldes mit Hilfe der findViewById() Methode. Diese erwartet als Argument die ID des EditText-Widgets. Welche ID dieses Widget in unserer Hierarchie von View-Objekten besitzt, erfahren wir über die Ressourcen-Datei R. Die ID selbst haben wir in der Layoutdatei activity_main.xml für das EditText-Widget definiert.

Nachdem wir eine Referenz auf das EditText-Objekt erhalten haben, lesen wir in Zeile 4 den Inhalt des Textfeldes aus. Der ausgelesene Wert ist immer vom Datentyp String, auch wenn in das Textfeld nur Zahlen eingegeben werden sollen.

Mit den Zeilen 6 bis 9 prüfen wir, ob der ausgelesene Wert leer ist. Falls ja, informieren wir den User mittels Fehlermeldung über die Falscheingabe und springen zurück zur aufrufenden Methode.

Falls der ausgelesene Wert nicht leer ist, wandeln wir ihn mit der Anweisung aus Zeile 11 in einen Integer-Wert um. Anschließend setzen wir den Inhalt des Textfeldes mit der Anweisung aus Zeile 12 zurück.

Mit diesen einfachen Schritten sind wir in der Lage ein EditText-Feld auszulesen, den Inhalt zu überprüfen und das Feld schließlich wieder zu leeren. Den ausgelesenen Wert können wir anschließend in die SQLite Datenbank eintragen.

2.2 Wie erkennt man, dass ein Button angeklickt wurde?

Auch das Erkennen von und Reagieren auf Button-Klicks ist in Android sehr einfach zu implementieren. Man benötigt dazu eine Referenz auf das Button-Objekt. Diese kann über die Ressourcen-Datei R und die findViewById() Methode angefragt werden.

Hat man die Referenz auf das Button-Objekt erhalten, muss nur noch ein OnClickListener für dieses registriert werden.

Der folgende Quellcode zeigt diese beiden Schritte beispielhaft:


In Zeile 3 fragen wir die Referenz auf das Button-Objekt an. Wir übergeben dazu der Methode findViewById() die ID des Buttons. Die ID haben wir in der Layoutdatei activity_main.xml für das Button-Widget definiert.

Für das Button-Objekt registrieren wir dann mit den Zeilen 5 bis 14 einen OnClickListener. Der OnClickListener ist ein Interface und besitzt genau eine abstrakte Methode, die onClick() Methode, welche wir überschreiben müssen.

Die onClick() Methode wird automatisch über einen in der View-Klasse implementierten Callback aufgerufen, sobald der Button angeklickt wurde. Somit können wir in der onClick() Methode erfassen, dass der Button geklickt wurde und entsprechend darauf reagieren.

In der onClick() Methode werden wir daher die Inhalte der beiden Textfelder unserer SQLite App auslesen, ihre Werte in die Datenbank speichern und anschließend den ListView aktualisieren.

Wenn ihr nicht genau wisst was ein Interface in Java ist, könnt ihr in unserem Java-Kurs mehr darüber erfahren.

Jetzt sind wir am Ende des theoretischen Teils dieser Lektion angekommen und sind bereit das erlangte Wissen in unser SQLite Projekt einzubringen. Dazu werden wir im nächsten Abschnitt die MainActivity-Klasse unserer SQLite App umstrukturieren und erweitern.

3. Erweitern der MainActivity unserer SQLite App

Nun werden wir die MainActivity-Klasse umstrukturieren und um einer neuen Methode erweitern. Über die MainActivity sollen die Benutzereingaben erfasst und in die SQLite Datenbank gespeichert werden.

Um dies zu realisieren nehmen wir die folgenden vier Änderungen am Quellcode der Klasse MainActivity vor:

  1. Einfügen der Import-Anweisungen – Zuerst importieren wir die benötigten Klassen.
  2. Überschreiben der Lifecycle-Callbacks – Wir werden die beiden Callback-Methoden onResume() und onPause() überschreiben und mit ihnen die Verbindung zur SQLite Datenbank verwalten.
  3. Überarbeiten der onCreate() Methode – Hier werden wir einige ausgelagerte Anweisungen löschen. Außerdem werden wir von hier die neue Methode activateAddButton() aufrufen.
  4. Definieren der activateAddButton() Methode – In dieser Methode registrieren wir einen OnClickListener für den Add-Button. Über den Listener werden wir die Textfelder auslesen und ihre Inhalte in die SQLite Datenbank schreiben, sobald der Button geklickt wurde.

Am Ende dieses Abschnitts haben wir nochmals den kompletten Quellcode der MainActivity-Klasse aufgeführt. Falls ihr bei den folgenden vier Schritten durcheinander kommt, könnt ihr ihn zur Kontrolle bzw. Orientierung nutzen.

Nun beginnen wir mit dem ersten Arbeitsschritt.

3.1 Einfügen der Import-Anweisungen

Wir öffnen als Erstes die Klassendatei MainActivity.java im Editorfenster von Android Studio über einen Klick auf den entsprechenden Eintrag in der linken Projektleiste.

Anschließend fügen wir den folgenden Quellcode unter den bereits vorhandenen Import-Anweisungen ein:


3.2 Überschreiben der relevanten Lifecycle-Callback Methoden

In dem zweiten Arbeitsschritt werden wir die beiden CallbackMethoden onResume() und onPause() überschreiben und dabei Code aus der onCreate() Methode in die neuen Methoden auslagern.

In der onResume() Methode werden wir die Verbindung zu unserer SQLite Datenbank herstellen, indem wir die Datenquelle öffnen. Anschließend lassen wir alle Inhalte der SQLite Datenbank in dem ListView anzeigen. Die Verbindung zur SQLite Datenbank werden wie in der onPause() Methode wieder schließen.

Jetzt fügen wir den folgenden Quellcode in den Methodenbereich der MainActivity-Klasse ein:


Der Quellcode ist zu großen Teilen bereits bekannt, da er direkt aus der onCreate() Methode ausgeschnitten und in die Callback-Methoden eingefügt wurde.

Eine Besonderheit ist der Aufruf der jeweiligen Super-Methode. Wird eine Lifecycle-Methode implementiert, muss unbedingt als Erstes die Implementierung der Basisklasse aufgerufen werden, bevor der eigene Code beginnt.

3.3 Überarbeiten der onCreate() Methode der MainActivity-Klasse

Im dritten Arbeitsschritt überarbeiten wir die onCreate() Methode unserer MainActivity-Klasse. Wir werden von der onCreate() Methode aus nur noch das Datenquellen-Objekt anlegen und den Add-Button aktivieren. Den Quellcode für das Öffnen und Schließen der Datenbankverbindung wurde in die beiden Lifecycle-Callbacks ausgelagert.

Die onCreate() Methode der MainActivity besteht nun aus folgenden Quellcode:


Der Aufruf der activateAddButton() Methode aus Zeile 9 ist neu hinzugekommen. Die Methode ist noch nicht definiert. Dies werden wir nun im nächsten Arbeitsschritt nachholen.

3.4 Definieren der activateAddButton() Methode

Kommen wir nun zum wichtigsten Arbeitsschritt dieser Lektion des Android SQLite Tutorials. Wir werden nun eine neue Methode definieren, mit der wir Klicks auf den Add-Button erfassen und entsprechend darauf reagieren.

Wie so etwas in Android implementiert wird, haben wir im oberen theoretischen Teil bereits besprochen. Jetzt ist es an der Zeit dies in die Praxis umzusetzen.

Wir fügen den folgenden Quellcode in den Methodenbereich der MainActivity-Klasse ein:


Mit den Anweisungen in den Zeilen 2 bis 4 fragen wir die Referenzen zu den Widget-Objekten an. Diese sind der Add-Button und die beiden EditText-Felder.

Den OnClickListener registrieren wir mit den Zeilen 6 bis 36 für das Button-Objekt. Dazu verwenden wir die Methode setOnClickListener(), die wir auf dem Button-Objekt aufrufen und ihr ein OnClickListener-Objekt übergeben.

Das OnClickListener-Objekt ist nichts Besonderes. Es besitzt als Elternklasse die Object-Klasse und muss die Interface-Methode onClick() implementieren. Die onClick() Methode wird über einen Callback aufgerufen, der für das View-Objekt, unseren Button, mit der Methode setOnClickListener() registriert wurde.

Wir erzeugen das OnClickListener-Objekt mit dem new Schlüsselwort und definieren es anschließend mit Hilfe einer anonymen Klasse, die nur eine einzige Methode besitzt, die onClick() Methode. In der onClick() Methode lesen wir mit den Zeilen 10 und 11 die beiden Textfelder aus.

Mit den if-Anweisungen in den Zeilen 13 bis 20 prüfen wir, ob in dem jeweiligen Textfeld etwas eingetragen wurde. Falls ein Feld leer ist, geben wir über die Methode setError() eine Fehlermeldung aus und beenden die onClick() Methode.

Den Wert des EditText-Feldes editTextQuantity wandeln wir in Zeile 22 in einen Integer-Wert um, da die Werte der Textfelder nur als String-Objekte vorliegen. Mit den beiden Anweisungen in den Zeilen 23 und 24 setzen wir den Wert der Textfelder zurück und löschen damit die eingetragenen Werte.

Anschließend speichern wir die ausgelesenen Werte mit der Anweisung aus Zeile 26 in die SQLite Datenbank. Die Arbeit überlassen wir unserer Datenquelle dataSource. Wir müssen ihrer Methode createShoppingMemo() nur die ausgelesenen Werte übergeben, den Rest übernimmt sie für uns.

Mit den Anweisungen in den Zeilen 28 bis 32 lassen wir das Eingabefeld verschwinden, so dass unsere Einkaufsliste komplett zu sehen ist. Anschließend geben wir alle Einträge der SQLite Datenbank mit Hilfe des ListViews auf dem Display aus.

Den Code für das Verstecken des Eingabefeldes haben wir aus einer Antwort bei StackOverflow entnommen. Ihr könnt ihn hier: How to hide soft keyboard on android after clicking outside EditText nachlesen.

3.5 Der komplette Quellcode der MainActivity-Klasse

Nun haben wir alle Änderungen an der MainActivity-Klasse vorgenommen.

Mit dem eingefügtem Quellcode reagieren wir auf Benutzereingaben und speichern die eingetragenen Werte in der SQLite Datenbank ab.

In dem unten angegebenen Quellcode ist die gesamte MainActivity-Klasse zur Kontrolle für euch aufgeführt. Die neu eingefügten Zeilen sind gelb markiert.

Der vollständiger Quelltext der Klasse MainActivity:


In Android Studio sollte die Klasse MainActivity nun wie folgt aussehen:

android sqlite onclicklistener

Die überarbeitete Klasse MainActivity mit Markierungen

In der oberen Abbildung sind die in den vier Arbeitsschritten vorgenommenen Änderungen mit einem blauen Rahmen markiert.

Die Import-Anweisungen sind mit A markiert. Die Änderungen an der onCreate() Methode der MainActivity mit B und die neuen Callback-Methode onResume() und onPasue() mit der wir die Verbindung zur SQLite Datenbank verwalten mit einem blauen C gekennzeichnet. Die Methode activateAddButton(), mit der wir den OnClickListener für den Add-Button registrieren und die Inhalte der beiden Textfelder auslesen, ist mit einem blauen D markiert.

Im nächsten Abschnitt werden wird die grafische Benutzeroberfläche unserer SQLite App testen und erstmals sinnvolle Werte in die Einkaufsliste über die Widget-Elemente eintragen.

4. Starten und Testen unserer SQLite App

In diesem Abschnitt werden wir unsere Android App ausführen und überprüfen, ob Einträge über das User Interface in die SQLite Datenbank gespeichert werden können.

Dazu werden wir zunächst die Anwendung auf einem Android Gerät ausführen und anschließend die zurückgelieferten Log-Meldungen in Android Studio analysieren. Zusätzlich prüfen wir auch, ob die Einträge korrekt im ListView der MainActivity auf dem Android Gerät angezeigt werden.

4.1 Ausführen der Android SQLite-App

Nun wollen wir unsere App ausführen und testen. Dazu installieren wir die Anwendung auf unser angeschlossenes Android Gerät (Smartphone oder Tablet) oder in einer AVD des Android Emulators.

Wie eine Android App installiert wird, könnt ihr in den folgenden beiden Teilen unseres großen Android App Programmieren Tutorials nachlesen:

Hier noch einmal in Kürze die wichtigsten Arbeitsschritte.

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:

android sqlite app starten

Android App über das Run App-Symbol starten

Nach einigen Momenten öffnet sich der Choose Device-Dialog. In ihm nehmen wir die folgenden Einstellungen vor:

  1. Radio Button Choose a running device aktivieren
  2. Das angeschlossene Android Gerät auswählen
  3. Mit einem Klick auf den OK-Button die Installation unserer App auf das Gerät starten
android choose device

Auswählen des angeschlossenen Android Geräts zum Aufspielen unserer App

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.2 Überprüfen der Log-Meldungen in Android Studio

Unsere SQLite-App sollte jetzt auf dem Android Gerät gestartet worden sein.

Um die Log-Meldungen zu überprüfen, öffnen wir in Android Studio die Android-Ansicht bei angeschlossenem Android Gerät.

In der unteren Abbildung sind die Log-Meldungen unserer Android App dargestellt. Der in Lektion 2 angelegte Log-Filter ist aktiviert (rote Markierung X). Unsere Meldungen werden im logcat-Textbereich angezeigt und sind von einem blauen Rahmen umschlossen (Markierung 1).

android sqlite onclicklistener log

Ausführen der SQLite-App – Überprüfen der Log-Meldungen in Android Studio mit aktivem Log-Filter

Uns werden die folgenden Log-Meldungen ausgegeben:

01: MainActivity﹕ Das Datenquellen-Objekt wird angelegt.
02: ShoppingMemoDataSource﹕ Unsere DataSource erzeugt jetzt den dbHelper.
03: ShoppingMemoDbHelper﹕ DbHelper hat die Datenbank: shopping_list.db erzeugt.
04: MainActivity﹕ Die Datenquelle wird geöffnet.
05: ShoppingMemoDataSource﹕ Eine Referenz auf die Datenbank wird jetzt angefragt.
06: ShoppingMemoDataSource﹕ Datenbank-Referenz erhalten. Pfad zur Datenbank: /data/data/de.programmierenlernenhq.shoppinglisthq/databases/shopping_list.db
07: MainActivity﹕ Folgende Einträge sind in der Datenbank vorhanden:
08: ShoppingMemoDataSource﹕ ID: 1, Inhalt: 2 x Testprodukt
09: ShoppingMemoDataSource﹕ ID: 2, Inhalt: 2 x Testprodukt
10: ShoppingMemoDataSource﹕ ID: 3, Inhalt: 2 x Testprodukt
11: ShoppingMemoDataSource﹕ ID: 4, Inhalt: 2 x Testprodukt
12: ShoppingMemoDataSource﹕ ID: 5, Inhalt: 2 x Testprodukt
13: MainActivity﹕ Die Datenquelle wird geschlossen.
14: ShoppingMemoDataSource﹕ Datenbank mit Hilfe des DbHelpers geschlossen.

Die erste Log-Meldung ist neu hinzugekommen und informiert uns darüber, dass eine Instanz der Datenqelle in der MainActivity angelegt wurde. Alle anderen Meldungen sind uns bereits bekannt. Anhand der Log-Meldungen können wir darauf schließen, dass unsere SQLite App auch nach den Umstrukturierungen der MainActivity-Klasse noch wie erwartet reagiert.

Als Nächstes deinstallieren wir die Anwendung von unserem Android Gerät, um die SQLite Datenbank zu löschen. Anschließend installieren wir die App wieder und starten sie neu, wodurch automatisch eine neue SQLite Datenbank-Datei angelegt wird.

Danach schreiben wir erstmals Einträge über die UI in die Tabelle der SQLite Datenbank. Das Ergebnis können wir in der unteren Abbildung betrachten, sie zeigt unsere SQLite App mit fünf selbst erstellten Einträgen:

android sqlite app ui

Unsere SQLite Datenbank App zeigt den Inhalt der ihrer Datenbank an

Wie zu erkennen ist, funktioniert unsere App wie erwartet. Die, über die beiden Textfelder, eingetragenen Werte werden in die Tabelle der SQLite Datenbank als Datensätze gespeichert und mit Hilfe des ListViews auf dem Android Gerät wieder ausgegeben.

Ein Video veranschaulicht die Funktion der SQLite App aber viel besser als ein Bild. Daher haben wir eine kleine Funktionspräsentation unserer SQLite App in Form eines Videos erstellt.

4.3 Video – Funktionspräsentation unserer SQLite App

In dem unteren Video haben wir einige Werte mit Hilfe der grafischen Benutzeroberfläche unserer Android App in die SQLite Datenbank eingetragen. In dem Video ist außerdem zu sehen, wie unsere SQLite App auf Fehleingaben reagiert.

Jetzt ist es möglich die Einkaufslisten-App sinnvoll zu nutzen. Leider gibt es noch ein Problem. Die Einträge lassen sich nicht über das User Interface löschen. Somit ist unsere SQLite App noch nicht vollständig.

Daher werden wir in der nächsten Lektion unserer Android App eine Lösch-Funktion spendieren, mit deren Hilfe die Einträge komfortabel aus der SQLite Datenbank entfernt werden können.

Zusammenfassung

In dieser Lektion unseres Android SQLite Tutorials haben wir die Benutzeroberfläche mit Funktionen hinterlegt. Dazu haben wir einen OnClickListener für den Add-Button registriert und reagieren damit auf Klicks der User.

In der onClick() Methode des OnClickListeners lesen wir die beiden EditText-Felder aus und speichern die ausgelesenen Werte in der Tabelle unserer SQLite Datenbank ab. Außerdem reagieren wir auf Fehleingaben, indem wir unseren Nutzern eine Fehlermeldung als Hinweis auf dem Android Gerät ausgeben.

Weiterhin haben wir in dieser Lektion die MainActivity umstrukturiert und zwei Lifecycle-Callbacks implementiert, über die wir die Verbindung zu der SQLite Datenbank verwalten. Mit der onResume() Methode stellen wir die Verbindung zur SQLite Datenbank her und mit der onPause() Methode schließen wir die Verbindung wieder.

Abschließend haben wir die neuen Funktionen unserer Android SQLite App überprüft und dadurch sichergestellt, dass die Datensätze korrekt in die Datenbank geschrieben und im ListView ausgeben werden.

Unsere Einkaufslisten-App kann jetzt schon genutzt werden. Es können Einträge über die Benutzeroberfläche in die SQLite Datenbank geschrieben werden und diese werden dann im ListView der MainActivity auf dem Display ausgegeben.

Momentan fehlt aber noch die Möglichkeit Einträge wider aus der SQLite Datenbank zu löschen. Dies werden wir uns in der nächsten Lektion des Android SQLite Tutorials vornehmen und unsere SQLite App um eine Lösch-Funktion erweitern.


Comments 2

  1. Pingback: Android SQLite Tutorial - Teil 2: SQLite Datenbank integrieren

  2. Pingback: Android SQLite Tutorial - Teil 1: SQLite Projekt anlegen

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *