Erste Schritte mit RxJava 2 für Android

Wenn Sie ein Android-Entwickler sind, haben Sie möglicherweise Gutes über RxJava gehört, eine beliebte Open-Source-Implementierung der ReactiveX-Bibliothek, die reaktive Programmierung für die Java Virtual Machine (JVM) bietet..

RxJava wurde entwickelt, um die Arbeit mit asynchronen Datenströmen zu vereinfachen - obwohl Sie wissen, dass RxJavas Definition von "Daten" ziemlich weit gefasst ist. Da RxJava eine JVM-kompatible Bibliothek ist, können Sie sie auf einer Vielzahl von Plattformen verwenden. In dieser Serie zeige ich Ihnen, wie Sie RxJava 2 für Android-Entwicklung verwenden.

Am Ende dieser Serie beherrschen Sie alle wichtigen Funktionen von RxJava 2, sodass Sie mit der Erstellung hochreaktiver Apps beginnen können, die eine breite Palette synchroner und asynchroner Daten verarbeiten können. Dabei wird Code verwendet, der übersichtlicher und handhabbarer ist, als Sie normalerweise wären allein mit Java zu erreichen.

Wenn Sie ein RxJava-1-Veteran sind und den Sprung zu RxJava 2 machen möchten, bieten wir Ihnen nicht nur eine Einführung für RxJava-Neulinge, sondern diese Serie wird dazu beitragen, diesen Übergang so reibungslos wie möglich zu gestalten. Ein Upgrade auf die neueste Version einer Bibliothek klingt zwar nicht nach großen Dingen, aber RxJava 2 ist kein typisches Update - es ist eine vollständige Neufassung von RxJava. Bei so vielen Änderungen ist es leicht, sich zu verwirren. Wenn Sie sich also etwas Zeit für die Einarbeitung in RxJava 2 aus der Perspektive eines Anfängers nehmen, können Sie auf lange Sicht viel Zeit und Frustration sparen.

In diesem ersten Beitrag werde ich beschreiben, was RxJava ist und welche Hauptvorteile es für Android-Entwickler bietet. Wir werden uns auch eingehend mit den Kernkomponenten von beschäftigen irgendein RxJava Projekt: Beobachter, Observables, und Abonnements. Am Ende dieses Lernprogramms haben Sie eine einfache Anwendung mit "Hello World" -Stil erstellt, die alle diese Kernkomponenten enthält.

Die anderen Hauptbausteine ​​von RxJava sind Operatoren. In Teil zwei werde ich untersuchen, wie Sie Operatoren zum Transformieren, Kombinieren, Filtern und Bearbeiten Ihrer Anwendungsdaten verwenden können.

In der letzten Folge werden wir uns über die RxJava-Kernbibliothek hinaus bewegen und einen Blick auf RxAndroid werfen, eine komplette Bibliothek, die alle Android-spezifischen Erweiterungen enthält, die Sie benötigen, um das volle Potenzial der reaktiven Programmierung für Android auszuschöpfen.

Wir haben viel zu tun, also fangen wir mit dem Wesentlichen an:

Was ist RxJava??

RxJava ist eine Bibliothek, mit der Sie Anwendungen im reaktiven Programmierstil erstellen können. Im Kern bietet die reaktive Programmierung eine saubere, effiziente Möglichkeit, Echtzeit-Datenströme, einschließlich Daten mit dynamischen Werten, zu verarbeiten und darauf zu reagieren.

Diese Datenströme müssen nicht zwingend sein haben Um die Form traditioneller Datentypen anzunehmen, behandelt RxJava fast alles als einen Datenstrom - von Variablen bis zu Eigenschaften, Caches und sogar Benutzereingabeereignissen wie Klicks und Wischen.

Die Daten, die von jedem Stream ausgegeben werden, können entweder ein Wert, ein Fehler oder ein Signal "abgeschlossen" sein, obwohl Sie die letzten beiden nicht unbedingt implementieren müssen. Nachdem Sie Ihre Daten emittierenden Streams erstellt haben, kombinieren Sie diese mit reaktiven Objekten, die diese verbrauchen, und führen Sie anschließend auf diese Daten aus. Dabei werden je nach Ausgabe des Streams unterschiedliche Aktionen ausgeführt. RxJava enthält eine ganze Reihe nützlicher Operatoren für die Arbeit mit Streams. So können Sie beispielsweise Filterung, Mapping, Verzögerung, Zählung und vieles mehr durchführen.

Um diesen Workflow aus Datenströmen und Objekten zu erstellen, die auf sie reagieren, erweitert RxJava das Observer-Softwareentwurfsmuster. Im Wesentlichen haben Sie in RxJava Beobachtbar Objekte, die einen Datenstrom ausgeben und dann enden, und Beobachter Objekte, die abonniert werden Beobachtbars. Ein Beobachter erhält jedes Mal eine Benachrichtigung, wenn sie zugewiesen wird Beobachtbar gibt einen Wert, einen Fehler oder ein abgeschlossenes Signal aus.

Bei RxJava geht es also auf hohem Niveau um:

  • Erstellen eines Beobachtbar.
  • Das geben Beobachtbar einige Daten zu emittieren.
  • Erstellen eines Beobachter.
  • Zuordnung der Beobachter zu einem Beobachtbar.
  • Geben die Beobachter Aufgaben, die auszuführen sind, wenn er eine Emission von seinem zugewiesenen Beobachtbar.

Warum RxJava??

Das Erlernen neuer Technologien erfordert Zeit und Mühe. Als datenorientierte Bibliothek ist RxJava nicht immer die einfachste API, mit der man sich auseinandersetzen kann.

Lassen Sie uns einige der wichtigsten Vorteile des Hinzufügens der RxJava-Bibliothek zu Ihren Android-Projekten herausfinden.

Kurzer lesbarer Code

Code, der komplex, ausführlich und schwer lesbar ist, ist immer schlechte Nachrichten. Chaotischer Code ist anfälliger für Fehler und andere Ineffizienzen, und wenn Fehler auftreten, wird es viel schwieriger, die Ursache dieser Fehler aufzuspüren, wenn der Code ein Durcheinander ist.

Selbst wenn Ihr Projekt fehlerfrei erstellt wird, kann komplexer Code Sie immer wieder in den Bann ziehen - normalerweise, wenn Sie sich dazu entscheiden, ein paar Monate später ein Update für Ihre App zu veröffentlichen, Ihr Projekt zu starten und sofort mit einer Mauer konfrontiert zu werden von verworrenen, verwirrenden Code!

RxJava vereinfacht den für die Verarbeitung von Daten und Ereignissen erforderlichen Code, indem es Ihnen ermöglicht, zu beschreiben, was Sie erreichen möchten, anstatt eine Liste von Anweisungen zu schreiben, die von Ihrer App verarbeitet werden können. RxJava bietet auch einen Standard-Workflow, mit dem Sie alle Daten und Ereignisse in Ihrer Anwendung erstellen können Beobachtbar, Erstelle ein Beobachter, das Beobachtbare diesem Beobachter zuordnen, spülen und wiederholen. Dieser formelle Ansatz ermöglicht sehr einfachen und für den Menschen lesbaren Code.

Multithreading leicht gemacht

Moderne Android-Anwendungen müssen multitaskingfähig sein. Zumindest erwarten Ihre Benutzer, dass Sie weiterhin mit der Benutzeroberfläche Ihrer App interagieren können, während Ihre Anwendung im Hintergrund Arbeiten ausführt, z. B. das Verwalten einer Netzwerkverbindung, das Herunterladen einer Datei oder das Abspielen von Musik. Das Problem ist, dass Android standardmäßig Single-Threading hat. Wenn Ihre App jemals erfolgreich zum Multi-Task-Modus wird, müssen Sie einige zusätzliche Threads erstellen.

Im Auslieferungszustand bietet Android eine Reihe von Möglichkeiten zum Erstellen zusätzlicher Threads wie Dienste und IntentServices, Keine dieser Lösungen ist jedoch besonders einfach zu implementieren und kann schnell zu komplexem, verbose Code führen, der fehleranfällig ist.

RxJava zielt darauf ab, die Erstellung von Android-Apps mit mehreren Threads zu vereinfachen, indem spezielle Scheduler und Operatoren bereitgestellt werden. Auf diese Weise können Sie auf einfache Weise den Thread angeben, in dem die Arbeit ausgeführt werden soll, und den Thread, in dem die Ergebnisse dieser Arbeit veröffentlicht werden sollen. RxJava 2.0 enthält standardmäßig eine Reihe von Schedulern, einschließlich Schedulers.newThread, welches ist insbesondere nützlich, da es einen neuen Thread erstellt.

Um den Thread, an dem die Arbeit ausgeführt wird, zu ändern, müssen Sie lediglich ändern, wo ein Beobachter ein Observable abonniert subscribeOn Operator. Zum Beispiel erstellen wir hier einen neuen Thread und legen fest, dass die Arbeit für diesen neuen Thread ausgeführt werden soll:  

observable.subscribeOn (Schedulers.newThread ())

Ein weiteres seit langem bestehendes Problem beim Multithreading unter Android ist, dass Sie die Benutzeroberfläche Ihrer App nur über den Haupt-Thread aktualisieren können. Normalerweise müssen Sie immer dann, wenn Sie die Ergebnisse einiger Hintergrundarbeiten auf der Benutzeroberfläche Ihrer App veröffentlichen müssen, ein dediziertes Element erstellen Handler.

Wieder hat RxJava eine viel einfachere Lösung. Du kannst den ... benutzen beobachten Operator, um anzugeben, dass ein Observable seine Benachrichtigungen mit einem anderen Scheduler senden soll. Dadurch können Sie die Observable-Daten grundsätzlich an den Thread Ihrer Wahl senden, einschließlich des Haupt-UI-Threads.

Dies bedeutet, dass Sie mit nur zwei Zeilen Code einen neuen Thread erstellen und die Ergebnisse der in diesem Thread ausgeführten Arbeit an den Haupt-Thread der Android-Benutzeroberfläche senden können:

 .subscribeOn (Schedulers.newThread ()) .observeOn (AndroidSchedulers.mainThread ())

Okay, also technisch wir schummeln hier ein bisschen wie AndroidSchedulers.mainThread ist nur als Teil der RxAndroid-Bibliothek verfügbar, auf die wir uns erst im dritten Teil konzentrieren werden. Dieses Beispiel gibt Ihnen jedoch einen Einblick in die Möglichkeiten von RxJava und RxAndroid, um einen Bereich der Android-Entwicklung zu vereinfachen, der bekanntermaßen zu kompliziert ist.

Erhöhte Flexibilität

Observables geben ihre Daten so aus, dass die Erstellung von Daten vollständig verborgen bleibt. Da Ihre Beobachter nicht einmal sehen können, wie die Daten erstellt wurden, können Sie Ihre Daten implementieren Beobachtbars in beliebiger Weise.

Sobald Sie Ihre implementiert haben Beobachtbars, RxJava bietet eine Vielzahl von Operatoren, mit denen Sie die Daten filtern, zusammenführen und transformieren können Beobachtbars. Sie können sogar mehr und mehr Operatoren miteinander verketten, bis Sie sie erstellt haben genau den Datenstrom, den Ihre Anwendung benötigt. 

Sie können beispielsweise Daten aus mehreren Streams kombinieren, den neu zusammengeführten Stream filtern und die resultierenden Daten dann als Eingabe für einen nachfolgenden Datenstrom verwenden. Denken Sie daran, dass in RxJava so ziemlich alles als Datenstrom behandelt wird. Sie können diese Operatoren sogar auf nicht-traditionelle "Daten" anwenden, beispielsweise auf Click-Ereignisse. 

Erstellen Sie Responsive Apps

Vorbei sind die Tage, an denen eine App davonkommen konnte, eine Seite mit Inhalten zu laden und darauf zu warten, dass der Benutzer auf die Schaltfläche tippt Nächster Taste. Heute muss Ihre typische mobile App in der Lage sein, auf eine ständig wachsende Vielzahl von Ereignissen und Daten zu reagieren, idealerweise in Echtzeit. Beispielsweise muss Ihre typische App für soziale Netzwerke ständig auf eingehende Likes, Kommentare und Freundschaftsanfragen achten, während Sie eine Netzwerkverbindung im Hintergrund verwalten und sofort reagieren, wenn der Benutzer auf den Bildschirm tippt oder wischt.

Die RxJava-Bibliothek wurde entwickelt, um eine Vielzahl von Daten und Ereignissen gleichzeitig und in Echtzeit verwalten zu können. Dies macht sie zu einem leistungsstarken Werkzeug für die Erstellung von reaktionsschnellen Anwendungen, die moderne mobile Benutzer erwarten.

Hinzufügen von RxJava zu Android Studio

Wenn Sie sich entschieden haben, dass RxJava Ihrer Android-Entwicklungspraxis etwas zu bieten hat, müssen Sie zunächst die Bibliothek zu Ihrem Projekt hinzufügen, um ein RxJava-Meister zu werden.

Erstellen Sie ein neues Android Studio-Projekt mit den Einstellungen Ihrer Wahl und öffnen Sie dann Ihre Modulebene build.gradle Datei und füge die neueste Version von hinzu io.reactivex.rxjava2: rxjava als Abhängigkeit. 

Zum Zeitpunkt des Schreibens war RxJava 2.0.5 die neueste Version, so meine build.gradle Datei sieht so aus:

Abhängigkeiten compile fileTree (Verzeichnis: 'libs', include: ['* .jar']) androidTestCompile ('com.android.support.test.espresso: espresso-core: 2.2.2'), exclude group: 'com. android.support ', modul:' support-annotations ') compile' com.android.support:appcompat-v7:25.1.0 'testCompile' junit: junit: 4.12 'compile' io.reactivex.rxjava2: rxjava: 2.0. 5 '

Wenn Sie dazu aufgefordert werden, klicken Sie auf Jetzt synchronisieren.

Als nächstes öffnen Sie Ihre Hauptaktivität Datei und fügen Sie die Importe hinzu, die Sie benötigen, um mit den Kernfunktionen von RxJava zu arbeiten:

import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; import io.reactivex.Observer; import io.reactivex.disposables.Disposable;

Wenn Sie von RxJava 1 migrieren, entsprechen diese Importe möglicherweise nicht Ihren Erwartungen, da RxJava 1 einen völlig anderen Paketnamen verwendet hat (rx um genau zu sein).

Dies ist jedoch keine willkürliche Namensänderung: Durch die verschiedenen Paketnamen haben Sie die Möglichkeit, RxJava 1 und RxJava 2 nebeneinander im selben Projekt zu verwenden. Wenn Sie ein Projekt, das RxJava 1 verwendet, auf halbem Weg durchlaufen, können Sie die RxJava 2-Bibliothek hinzufügen und sofort mit den aktualisierten zwei Funktionen beginnen, ohne Ihren RxJava 1-Code zu beschädigen.

Wenn Sie Ihre RxJava-Reise mit Version 2 beginnen, sollten Sie sich dessen bewusst sein, wenn Sie RxJava-Tutorials oder -Code mit der rx Paketname, dann ist dies RxJava 1-Code und es ist unwahrscheinlich, dass er mit der Bibliothek der Version 2 kompatibel ist.

Die Bausteine ​​von RxJava

Bisher haben wir RxJava nur auf sehr hohem Niveau betrachtet. Es ist an der Zeit, genauer zu werden und zwei der wichtigsten Komponenten, die während Ihrer gesamten RxJava-Arbeit immer wieder auftauchen, eingehend zu untersuchen: Beobachters und Beobachtbars.

Am Ende dieses Abschnitts haben Sie nicht nur ein solides Verständnis dieser beiden Kernkomponenten, sondern Sie haben auch eine voll funktionsfähige Anwendung erstellt, die aus einer Beobachtbar das emittiert Daten und eine Beobachter das reagiert auf diese emissionen.

Erstelle ein Beobachtbar

Ein Beobachtbar ist ähnlich einem Iterable Wenn eine Sequenz gegeben ist, durchläuft es diese Sequenz und gibt jedes Element aus, obwohl Beobachtbars beginnen normalerweise erst dann mit dem Senden von Daten Beobachter abonniert sie.

Jedes Mal ein Beobachtbar sendet ein Element aus und benachrichtigt seine zugewiesenen Beobachter Verwendung der onNext () Methode. Einmal ein Beobachtbar hat alle seine Werte übertragen, beendet es durch Aufruf von:

  • onComplete: Wird aufgerufen, wenn die Operation erfolgreich war.
  • onError: Wird aufgerufen, wenn ein Ausnahme wurde geworfen.

Schauen wir uns ein Beispiel an. Hier erstellen wir ein Observable, das die Zahlen ausstrahlt 1, 2, 3 und 4, und endet dann.

Beobachtbar observable = Observable.create (neues ObservableOnSubscribe() @Override public void subscribe (ObservableEmitter.) e) wirft Exception // verwendet onNext, um jedes Element im Stream auszugeben // e.onNext (1); e.onNext (2); e.onNext (3); e.onNext (4); // Wenn das Observable alle Elemente in der Sequenz ausgegeben hat, rufen Sie onComplete auf. // e.onComplete (); );

Beachten Sie, dass ich in diesem Beispiel genau schreibe, was passiert, also lassen Sie sich nicht durch die Menge an Code abschrecken! Dies ist viel mehr Code, als Sie normalerweise zum Erstellen verwenden Beobachtbars in Ihren realen RxJava-Projekten.

Erstellen Sie einen Observer

Beobachters sind Objekte, die Sie einem zuordnen Beobachtbar, Verwendung der abonnieren() Operator. Einmal ein Beobachter ist ein abonniert Beobachtbar, es wird immer reagieren, wenn es ist Beobachter gibt eine der folgenden aus:

  • onNext: Das Beobachtbar hat einen Wert ausgegeben.
  • onError: Ein Fehler ist aufgetreten.
  • onComplete: Das Beobachtbar hat alle seine Werte ausgegeben.

Lass uns einen erstellen Beobachter das ist für unsere 1, 2, 3, 4 abonniert Beobachtbar. Um die Dinge einfach zu halten, das hier Beobachter werde darauf reagieren onNext, onError und onComplete durch Drucken einer Nachricht an Android Studio Logcat Monitor:

Beobachter Beobachter = neuer Beobachter() @Override public void onSubscribe (Disposable d) Log.e (TAG, "onSubscribe:");  @Override public void onNext (Integer-Wert) Log.e (TAG, "onNext:" + value);  @Override public void onError (Throwable e) Log.e (TAG, "onError:");  @Override public void onComplete () Log.e (TAG, "onComplete: All Done!"); ; // Erstelle unser Abonnement // observable.subscribe (observer);

Öffnen Sie den Logcat-Monitor von Android Studio, indem Sie die Option auswählen Android-Monitor Klicken Sie unten im Android Studio-Fenster auf die Registerkarte (dort, wo sich der Cursor in der Abbildung unten befindet) und wählen Sie dann die Option aus Logcat Tab.

Um diesen Code zu testen, schließen Sie entweder Ihr physisches Android-Gerät an Ihren Entwicklungscomputer an oder führen Sie Ihr Projekt auf einem kompatiblen AVD-Gerät aus. Sobald Ihre App auf dem Bildschirm angezeigt wird, sollten Sie die von Ihrem Observable ausgegebenen Daten sehen.

Ein Observable mit weniger Code erstellen

Obwohl unser Projekt Daten erfolgreich emittiert, ist der von uns verwendete Code nicht genau festgelegt - insbesondere der Code, den wir zur Erstellung unserer verwenden Beobachtbar.  

Glücklicherweise bietet RxJava eine Reihe von Komfortmethoden, mit denen Sie eine Beobachtbar mit viel weniger Code:

1. Observable.just ()

Du kannst den ... benutzen .gerade() Operator, um ein beliebiges Objekt in ein Beobachtbar. Das Ergebnis Beobachtbar Das ursprüngliche Objekt wird dann ausgegeben und abgeschlossen.

Zum Beispiel erstellen wir hier eine Beobachtbar das wird eine einzige Zeichenfolge an alle ausgeben Beobachter:

Beobachtbar observable = Observable.just ("Hallo Welt!");

2. Observable.from ()

Das .von() Mit dem Operator können Sie eine Sammlung von Objekten in einen beobachtbaren Stream konvertieren. Sie können ein Array in ein konvertieren Beobachtbar mit Beobachtbar.vonArray, ein Abrufbar In ein Beobachtbar mit Observable.fromCallable, und ein Iterable In ein Beobachtbar mit Observable.fromIterable.

3. Observable.range ()

Du kannst den ... benutzen .Angebot() Operator, um eine Reihe sequentieller Ganzzahlen auszugeben. Die erste Ganzzahl, die Sie angeben, ist der Anfangswert, und die zweite ist die Anzahl der Ganzzahlen, die Sie ausgeben möchten. Zum Beispiel:

Beobachtbar beobachtbar = beobachtbarer Bereich (0, 5);

4. Observable.interval ()

Dieser Operator erstellt eine Beobachtbar Das gibt eine unendliche Folge aufsteigender Ganzzahlen aus, wobei jede Emission durch ein von Ihnen gewähltes Zeitintervall getrennt wird. Zum Beispiel:

Beobachtbar observable = Observable.interval (1, TimeUnit.SECONDS)

5. Observable.empty ()

Das leeren() Operator erstellt eine Beobachtbar das keine Elemente ausgibt, aber normal beendet wird, was nützlich sein kann, wenn Sie schnell ein erstellen möchten Beobachtbar zu Testzwecken.  

Beobachtbar observable = Observable.empty ();

Fazit

In diesem Artikel haben wir die grundlegenden Bausteine ​​von RxJava behandelt.

An diesem Punkt wissen Sie, wie Sie erstellen und damit arbeiten Beobachter und Observables, und wie man ein Abo erstellt, damit Ihr Observables kann mit dem Senden von Daten beginnen. Wir haben uns auch ein paar Operatoren angesehen, mit denen Sie eine Reihe von unterschiedlichen Funktionen erstellen können Observables, mit viel weniger Code.

Operatoren sind jedoch nicht nur ein praktischer Weg, um die Menge an Code zu reduzieren, den Sie schreiben müssen! Erstellen eines Beobachter und ein Beobachtbar ist einfach genug, aber bei den Operatoren beginnt man wirklich zu sehen, was mit RxJava möglich ist. 

Im nächsten Beitrag werden wir einige der leistungsstärksten Operatoren von RxJava kennenlernen, einschließlich der Operatoren, die endlich Multithreading auf Android zu einem schmerzfreien Erlebnis machen können. Bleiben Sie dran, um die wahre Leistungsfähigkeit der RxJava-Bibliothek kennenzulernen.

In der Zwischenzeit können Sie sich auf Envato Tuts einige unserer anderen Beiträge und Kurse zur Android-Entwicklung ansehen+!

Beobachtbare Datenflussdiagramme stammen aus der ReactiveX-Dokumentation und sind unter der Creative Commons Attribution 3.0 License lizenziert.