Einen Event-Bus mit LiveData implementieren

Was Sie erstellen werden

Beim letzten Google I / O hat das Android-Team eine Reihe leistungsstarker Android-Architekturkomponenten veröffentlicht. Sie nennen es:

Eine Sammlung von Bibliotheken, mit deren Hilfe Sie robuste, testbare und wartbare Apps erstellen können. Beginnen Sie mit Klassen zur Verwaltung des Lebenszyklus Ihrer UI-Komponenten und zum Behandeln der Datenpersistenz.

Wenn Sie noch nichts darüber erfahren haben, empfehlen wir Ihnen dringend, unsere großartige Serie hier auf Envato Tuts + über Android Architecture-Komponenten von Tin Megali zu lesen. Stellen Sie sicher, dass Sie eintauchen! 

In diesem Tutorial zeige ich Ihnen, wie Sie das verwenden Lebensdaten Komponenten aus den Android Architectural-Komponenten, um einen Ereignisbus zu erstellen. Ein Event-Bus kann verwendet werden, um effektiv zwischen Android-Komponenten oder zwischen den Schichten Ihrer Anwendung zu kommunizieren, z. B. zur Kommunikation mit einem Aktivität von einem IntentService dass das Herunterladen einer Datei abgeschlossen ist. 

Wir werden eine sehr einfache App erstellen, die eine auslöst IntentService etwas zu tun - von einem Aktivität. Unsere IntentService wird dann wieder mit dem kommunizieren Aktivität wenn die arbeit abgeschlossen ist. Unser Kommunikationskanal wird von der sein Lebensdaten Bibliothek. 

Voraussetzungen

Um diesem Tutorial folgen zu können, benötigen Sie:

  • Android Studio 3.0 oder höher
  • Kotlin Plugin 1.1.51 oder höher
  • ein grundlegendes Verständnis der Android - Architekturkomponenten (insbesondere der Lebensdaten Komponente)
  • ein grundlegendes Verständnis eines Ereignisbusses

In meiner Kotlin From Scratch-Serie können Sie alle Besonderheiten der Kotlin-Sprache erlernen.

  • Kotlin von Anfang an: Variablen, Basistypen und Arrays

    Kotlin ist eine moderne Programmiersprache, die Java-Bytecode kompiliert. Es ist kostenlos und Open Source und verspricht, die Kodierung für Android noch mehr Spaß zu machen.
    Chike Mgbemena
    Kotlin
  • Kotlin von Grund auf: Klassen und Objekte

    Erhalten Sie eine Einführung in die objektorientierte Programmierung in Kotlin, indem Sie etwas über Klassen lernen: Konstruktoren und Eigenschaften, Casting und erweiterte Klassenfunktionen.
    Chike Mgbemena
    Kotlin

1. Erstellen Sie ein Android Studio-Projekt

Starten Sie Android Studio 3 und erstellen Sie ein neues Projekt mit einer leeren Aktivität Hauptaktivität

2. Fügen Sie die Lebenszykluskomponenten hinzu

Nachdem Sie ein neues Projekt erstellt haben, geben Sie das an Lebenszyklus und das Lebensdaten Artefakte in Ihrem App-Modul build.gradle. Beachten Sie, dass sich die neuen Architekturkomponenten zum jetzigen Zeitpunkt in einer stabilen Version befinden. Das bedeutet, dass Sie sie in Produktions-Apps verwenden können. 

Abhängigkeiten Implementierungsdateibaum (Verzeichnis: 'libs', include: ['* .jar']) Implementierung "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" Implementierung "com.android.support:appcompat-v7: 26.1.0 'Implementierung "android.arch.lifecycle: Laufzeit: 1.0.3" Implementierung "android.arch.lifecycle: Erweiterungen: 1.0.0"

Diese Artefakte sind im Maven-Repository von Google verfügbar. 

alle Projekte Repositorys google () jcenter ()

Durch das Hinzufügen der Abhängigkeiten haben wir Gradle beigebracht, wie man die Bibliothek findet. Vergessen Sie nicht, Ihr Projekt nach dem Hinzufügen zu synchronisieren. 

3. Erstellen Sie die Lebenszyklusbesitzer Aktivitätsunterklasse

Hier unser Hauptaktivität implementiert die Lebenszyklusbesitzer Schnittstelle. 

import android.arch.lifecycle.Lifecycle import android.arch.lifecycle.LifecycleOwner importieren android.arch.lifecycle.LifecycleRegistry importieren android.arch.lifecycle.Observer import android.content.Intent import android.os.Bundle import android.support.v7 .app.AppCompatActivity import android.view.View import android.widget.Button import android.widget.TextView-Klasse MainActivity: AppCompatActivity (), LifecycleOwner privates Registrierungsregister = LifecycleRegistry (this) überschreibt fun onCreate (savedInstanceState: Bundle?) .onCreate (savedInstanceState) setContentView (R.layout.activity_main) registry.handleLifecycleEvent (Lifecycle.Event.ON_CREATE) überschreibt fun getLifecycle (): Lifecycle = Registry-Überschreibung fun onStart () super.onStart () registry.handLucachecan. Event.ON_START) überschreiben fun onResume () super.onResume () registry.handleLifecycleEvent (Lifecycle.Event.ON_RESUME) überschreibt fun onPause () super.onPause () registry.handleLifecycleEvent (Lifecycle.Event.ONvent).  override fun onStop () super.onStop () registry.handleLifecycleEvent (Lifecycle.Event.ON_STOP) überschreibt fun onDestroy () super.onDestroy () registry.handleLifecycleEvent (Lifecycle.Event.ON_DESTROY) 

In unserer Aktivität werden lediglich die Standardereignisse des Aktivitätslebenszyklus behandelt. In jedem der Lebenszyklusereignisse wird das Ereignis aufgerufen registry.handleLifecycleEvent (), Übergeben des entsprechenden Ereignisses als Parameter.   

4. Erstellen Sie das Layout

Wir haben nur eine Taste das löst den Dienst aus. EIN Textvorschau (standardmäßig nicht sichtbar) zeigt den Text an "Arbeit abgeschlossen!" wenn der Dienst an uns kommuniziert Hauptaktivität

  

5. Initialisieren Sie die Widgets

Wir haben unser erklärt doWorkButton und resultTextView Eigenschaften innerhalb der Hauptaktivität Klasse mit der lateinit Modifikator. Wir initialisieren sie dann im onCreate () Methode. Jederzeit die doWorkButton geklickt wird, deaktivieren wir es (um ein Klicken auf die Schaltfläche mehr als einmal zu verhindern) und starten Sie unsere MyIntentService (Wir werden in Kürze dazu kommen). 

Klasse MainActachAktualität: AppCompatActachine (), LifecycleOwner private lateinit var doWorkButton: Schaltfläche private lateinit var resultTextView: TextView überschreiben den Spaß onCreate (savedInstachutateRate: Bundle?) //… doWorkButton = findViewById (R.id.btn_download). isEnabled = false resultTextView.visibility = View.INVISIBLE val serviceIntent = Intent (dies ist MyIntentService :: class.java) startService (serviceIntent) resultTextView = findViewById (R.id.tv_result) //…

6. Erstellen Sie die benutzerdefinierte Ereignisklasse

Wir erstellen einfach eine einfache Ereignisnachrichtenklasse, die wir auf dem Ereignisbus (oder Lebensdaten). 

Datenklasse CustomEvent (val eventProp: String)

Sie können dieser Klasse weitere Eigenschaften hinzufügen, wenn Sie möchten. 

7. Service-Implementierung

Wir haben einen IntentService mit dem Namen implementiert MyIntentService. Erinnere dich daran IntentService ist außerhalb des Aktivitätsbereichs und verfügt über einen Hintergrundthread. Es wird daher empfohlen, zeitaufwendige Aufgaben auszuführen, z. B. das Herunterladen oder Abrufen von Remote-Daten über eine darin enthaltene API.  

Beachten Sie jedoch, dass in Android 8.0, wenn Sie Ihre nicht erstellen IntentService ein Vordergrunddienst durch Verwendung von startForeground (), Das Android-System lässt Ihren Dienst nicht länger als 1 Minute laufen. Andernfalls wird er sofort gestoppt. Dieser Mechanismus dient zur effizienten Verwaltung von Systemressourcen wie der Akkulaufzeit. Wenn Ihre App auf Android 8.0 ausgerichtet ist, wird empfohlen, stattdessen den JobIntentService zu verwenden. 

import android.app.IntentService import android.arch.lifecycle.MutableLiveData import android.content.Intent import android.os.SystemClock-Klasse MyIntentService: IntentService ("MyIntentService") Begleitobjekt var BUS = MutableLiveData() override fun onHandleIntent (intent: Intent?) // Arbeit simulieren SystemClock.sleep (3000) // Wenn die Arbeit abgeschlossen ist val event = CustomEvent ("value") if (BUS.hasActiveObservers ()) BUS.postValue (Ereignis) else // Benachrichtigung anzeigen

Wir erstellen ein namenloses Begleitobjekt, dessen Begleiterklasse ist MyIntentService. Dieses Begleitobjekt hat eine Eigenschaft, die aufgerufen wird BUS, Das ist ein Beispiel von MutableLiveData.  Denken Sie daran, dass Begleitobjekte Singletons sind. Dies bedeutet, dass nur eine einzige Instanz von BUS existiert. Wir haben auch unsere bestanden CustomEvent als typargument für das generische MutableLiveData Klasse. 

Denken Sie daran, dass die MutableLiveData Klasse ist eine Unterklasse von Lebensdaten-und hat eine Methode aufgerufen postValue () das kann von einem Hintergrundthread aus aufgerufen werden. 

öffentliche Klasse MutableLiveData erweitert LiveData @Override public void postValue (T-Wert) super.postValue (Wert);  @Override public void setValue (T-Wert) super.setValue (Wert); 

Innerhalb onHandleIntent (), Wir haben unsere Geschäftslogik. Denken Sie daran, dass diese Methode für einen Hintergrundthread aufgerufen wird (einer der Hauptunterschiede zwischen einem IntentService und ein normaler Bedienung). Das IntentService endet sofort von selbst, wenn die onHandleIntent () Methode beendet seine Arbeit.  

In unserem eigenen Fall simulieren wir die gerade ausgeführten Arbeiten (dies kann ein Dateidownload oder die Kommunikation mit einer Remote-API sein), indem der aktuelle Thread für 30 Sekunden im Ruhezustand gehalten wird. Wir haben dann geprüft, ob unsere BUS hat aktive Beobachter, die die hasActiveObservers () Methode. Wenn es welche gibt, benachrichtigen Sie sie und leiten Sie sie mit der Methode an sie weiter postValue (), ansonsten können wir einfach eine Benachrichtigung anzeigen (diese wurde im obigen Beispiel aus Gründen der Kürze nicht codiert). 

Denken Sie daran, den Dienst in Ihre Manifestdatei aufzunehmen.

8. Implementierung des Beobachters

Wir brauchen mindestens einen Beobachter, damit unser Mechanismus nützlich ist. Also in der Hauptaktivität Klasse werden wir einen anonymen Beobachter abonnieren. 

Klasse MainActivity: AppCompatActivity (), LifecycleOwner //… überschreibt den Spaß onCreate (savedInstanceState: Bundle?) //… MyIntentService.BUS.observe (dies, Observer event -> resultTextView.visibility = View.VISIBLE downloadButton.isEnabled = true Log.d ("MainActivity", Ereignis? .EventProp)) //…

In der onCreate () von Hauptaktivität, wir haben den Eventbus bekommen BUS von MyIntentService. Dann haben wir einen Beobachter für den Event-Bus registriert (d. H. Lebensdaten) Verwendung der beobachten() Methode. Als Nächstes haben wir einen anonymen Beobachter registriert und inline geschrieben Hauptaktivität wie Lebenszyklusbesitzer. Dieser anonyme Beobachter wird benachrichtigt, wenn einer der folgenden Fälle eintritt:

  • Es sind bereits Daten im vorhanden Lebensdaten wenn es abonniert. 
  • Die Daten im Lebensdaten wird modifiziert. 

Wenn einer dieser Fälle auftritt, erhalten wir die Veranstaltung Daten (aus dem Lebensdaten) auf dem Hauptanwendungsthread als Eingabe für das Lambda. Wir machen dann im Inneren des Lambdas folgendes:

  • Mach das resultTextView sichtbar.
  • Aktivieren Sie die doWorkButton.
  • Protokollieren Sie unsere benutzerdefinierten Ereigniseigenschaften eventProp Wert für Logcat.

Denken Sie an folgendes über Lebensdaten:

  • Wenn ein neuer Beobachter an unserem hängt Lebensdaten nach einer Konfigurationsänderung, Lebensdaten sendet die letzten Daten, die er erhalten hat, an den Beobachter - auch ohne dass wir ihn ausdrücklich dazu auffordern. Mit anderen Worten, dies geschieht automatisch. 
  • Wenn der Lebenszyklusbesitzer zerstört wird, wird der Beobachter automatisch abgemeldet. 
  • Endlich, Lebensdaten ist ein beobachtbares, das den Lebenszyklus berücksichtigt. Laut den Unterlagen:
LiveData ist eine Klasse für beobachtbare Datenhalter. Im Gegensatz zu einem regulären Observable ist LiveData lebenszyklusabhängig, dh es berücksichtigt den Lebenszyklus anderer App-Komponenten wie Aktivitäten, Fragmente oder Services. Dadurch wird sichergestellt, dass LiveData nur App-Observer aktualisiert, die sich im aktiven Lebenszyklus befinden.

9. Testen der App

Schließlich können Sie die App ausführen! Drücke den Arbeite und nach 30 Sekunden sehen Sie das Ergebnis. 

Den vollständigen Quellcode erhalten Sie in unserem GitHub-Repo.

Fazit

In diesem Tutorial haben Sie gelernt, wie Sie die Lebensdaten Komponenten aus den Android Architectural-Komponenten, um einen Event-Bus zu erstellen, um effektiv mit den Komponenten Ihrer App zu kommunizieren. 

Ich nehme an, Sie kennen andere Bibliotheken, die Sie für denselben Zweck verwenden können, wie beispielsweise den Android LocalBroadcastManager oder den beliebten greenrobot EventBus, um einen Event-Bus in Ihrer Android-Anwendung zu implementieren. Sie können das mit dem sehen Lebensdaten Stattdessen ist es vorzuziehen, weil Sie das Schreiben von Boilerplate oder verbose Code vermeiden Lebensdaten bietet Ihnen eine bessere Flexibilität. 

Weitere Informationen zum Codieren für Android finden Sie in Envato Tuts. Hier finden Sie einige unserer anderen Kurse und Tutorials+!