Advertisement
  1. Code
  2. Android SDK

Java 8 für Android: Saubererer Code mit Lambda-Ausdrücken

by
Read Time:15 minsLanguages:
This post is part of a series called Java 8 for Android Development.
Java 8 for Android Development: Default and Static Methods

German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)

Lambda-Ausdrücke können Ihnen dabei helfen, Boilerplate-Code aus Ihren Projekten zu entfernen und große Datenmengen mühelos zu verarbeiten. Erfahren Sie, wie Sie mit diesem detaillierten Blick auf die Java 8-Funktionen, die Sie heute in Ihren Android-Projekten verwenden können, arbeiten können.

Java 8 für Android

Java 8, das bereits im März 2014 eingeführt wurde, war ein großer Fortschritt für die Programmiersprache und führte eine Liste von Funktionen ein, die versprachen, die Codierung in Java einfacher und präziser als je zuvor zu gestalten.

Leider würden Android-Entwickler die Vorteile dieser Funktionen für eine Weile nicht spüren, da Google experimentierte, Java 8 über Jack (Java Android Compiler Kit) auf die Android-Plattform zu bringen, bevor es Jack zugunsten der nativen Unterstützung von Java 8 in Android Studio ablehnte.

Mit der Veröffentlichung von Android Studio 3.0 haben wir endlich eine Version der Android-Toolchain, die einige der wichtigsten Funktionen von Java 8 unterstützt.

In dieser Serie werde ich Ihnen zeigen, wie Sie eine Menge Code aus Ihren Projekten entfernen, große Datenmengen mühelos verarbeiten und sogar einen funktionaleren Stil in Ihre Java-Programmierung mit Java 8 integrieren können Werfen Sie einen detaillierten Blick auf die Java 8-Funktionen, die Sie heute verwenden können.

Wenn Sie diese Serie abgeschlossen haben, können Sie alle folgenden Java 8-Funktionen in Ihren Android-Projekten verwenden:

  • Lambda-Ausdrücke
  • Methodenreferenzen
  • Standardmethoden
  • statische Schnittstellenmethoden
  • Typ Anmerkungen
  • Anmerkungen wiederholen
  • funktionale Schnittstellen
  • die Stream-API

In diesem ersten Beitrag werden wir uns die Funktion ansehen, die bei der ersten Veröffentlichung von Java 8 am meisten Aufsehen erregt hat und die für Android-Entwickler den größten Unterschied bedeuten kann: Lambda-Ausdrücke.

Vorbereiten Ihrer Entwicklungsumgebung

Bevor Sie irgendwelche Java 8-Funktionen verwenden können, müssen Sie sicherstellen, dass Ihre Entwicklungsumgebung für die Unterstützung dieser Java-Version eingerichtet ist.

Wenn Sie Java 8 noch nicht installiert haben, müssen Sie das neueste JDK8 herunterladen und den JDK-Pfad von Android Studio aktualisieren, damit er auf das JDK8-Paket verweist:

  • Starten Sie Android Studio.
  • Wählen Sie in der Android Studio-Symbolleiste Datei > Projektstruktur… aus.
  • Aktualisieren Sie das JDK-Speicherort-Feld so, dass es auf Ihr neu heruntergeladenes JDK8-Paket verweist.

Wenn Sie nicht sicher sind, welche Java-Version Sie installiert haben, können Sie dies überprüfen, indem Sie ein Terminalfenster (wenn Sie ein Mac-Benutzer sind) oder eine Eingabeaufforderung (wenn Sie unter Windows arbeiten) öffnen und dann Folgendes ausführen Befehl:

Wenn Build 1.8 oder höher zurückgegeben wird, können Sie loslegen!

Außerdem muss Android Studio 3.0 Preview 1 oder höher installiert sein. Um die Wahrscheinlichkeit von Fehlern und anderen seltsamen Verhaltensweisen zu verringern, wird jedoch empfohlen, die neueste Version von Android Studio 3.0 zu installieren - unabhängig davon, ob es sich um eine Beta-Version oder eine Vorschau handelt oder Idealerweise eine stabile Version von Android Studio 3.0 (die zum Zeitpunkt des Schreibens noch nicht verfügbar war).

Als Nächstes müssen Sie einige Änderungen an den build.gradle-Dateien Ihres Projekts vornehmen. Normalerweise müssen Sie nur ein paar Codezeilen hinzufügen, um anzugeben, dass dieses Projekt Java 8-Bytecode generieren soll. Wenn Sie zuvor mit dem Jack-Compiler oder dem beliebten Retrolambda-Projekt mit Java 8-Funktionen experimentiert haben, müssen Sie diese Werkzeuge deaktivieren, bevor Ihr Projekt die neue und verbesserte Java 8-Unterstützung verwenden kann, die von der Standard-Toolchain von Android bereitgestellt wird .

In den folgenden Abschnitten werde ich Ihnen zeigen, wie Sie die Java 8-Unterstützung aktivieren und bei Bedarf Retrolambda und Jack deaktivieren.

Hinzufügen von Java 8-Unterstützung zu einem neuen Projekt

Angenommen, Sie haben Jack noch nicht aktiviert oder Retrolambda nicht als Projektabhängigkeit hinzugefügt. Der erste Schritt besteht darin, die Datei build.gradle auf Projektebene zu öffnen und sicherzustellen, dass Sie Version 3.0.0-alpha1 (oder höher) von verwenden Gradle für Android Plugin:

Öffnen Sie als Nächstes jede build.gradle-Datei auf Modulebene, in der Sie Java 8-Funktionen verwenden möchten, und legen Sie die Sprachstufe des Quellcodes und die Version des generierten Java-Bytecodes auf JavaVersion.VERSION_1_8 fest:

Wenn Sie von Jack migrieren

Der Jack-Compiler ist möglicherweise veraltet, aber solange er aktiviert ist, verwendet Ihr Projekt die von Jack bereitgestellte Java 8-Unterstützung anstelle der von der Standard-Toolchain von Android bereitgestellten Unterstützung.

Die Verwendung eines veralteten Tools ist nie eine gute Idee, aber es gibt einige zusätzliche Gründe, warum Sie vom Jack-Compiler migrieren sollten, falls Sie dies noch nicht getan haben.

Erstens unterstützt Jack möglicherweise eine Teilmenge der Java 8-Funktionen, aber im Gegensatz zur Standard-Toolchain werden keine Bibliotheken von Drittanbietern unterstützt, die diese Funktionen verwenden. Wenn Sie also Jack verwenden, schränken Sie Ihre Optionen für Bibliotheken von Drittanbietern sofort ein .

Zweitens nimmt der Jack-Compiler Java-Code und konvertiert ihn direkt in Dex, ohne Zwischenbytecode zu erzeugen. Solange Jack aktiviert ist, können Sie keines der Tools verwenden, die auf dieser Zwischenausgabe basieren, z. B. Anmerkungsprozessoren und Bytecode-Analysatoren.

Um den Jack-Compiler zu deaktivieren, öffnen Sie Ihre build.gradle-Datei auf Modulebene und entfernen Sie den jackOptions-Abschnitt. Lassen Sie jedoch den compileOptions-Block intakt:

Wenn Sie von Retrolambda migrieren

Ähnlich wie Jack unterstützt Retrolambda keine Bibliotheken von Drittanbietern, die Java 8-Sprachfunktionen verwenden. Wenn Ihr Projekt für die Verwendung des Retrolambda-Plugins eingerichtet ist, sollten Sie dieses Plugin entfernen, damit Ihr Projekt auf die Standard-Toolchain zurückgesetzt werden kann.

Öffnen Sie Ihre build.gradle-Datei auf Projektebene und entfernen Sie Retrolambda als Projektabhängigkeit:

Entfernen Sie dann das Retrolambda-Plugin aus jeder build.gradle-Datei auf Modulebene:

Testen Sie Ihren Java 8-Support

Der einfachste Weg, um zu überprüfen, ob Ihr Projekt jetzt Java 8 unterstützt, besteht darin, einen kurzen Lambda-Ausdruck zu schreiben und zu prüfen, ob Ihr Projekt noch kompiliert wird.

Fügen Sie Ihrer Benutzeroberfläche eine Schaltfläche hinzu (oder verwenden Sie eine bereits vorhandene Schaltfläche), und implementieren Sie dann einen onClickListener für diese Schaltfläche mithilfe eines Lambda-Ausdrucks. Machen Sie sich keine Sorgen, wenn der folgende Code jetzt nicht viel Sinn macht - er wird am Ende dieses Artikels erscheinen!

Test your lambda expression by triggering the Java 8 toastTest your lambda expression by triggering the Java 8 toastTest your lambda expression by triggering the Java 8 toast

Überprüfen Sie, ob Ihr Projekt noch kompiliert wird, indem Sie entweder im angezeigten Banner die Option Synchronisieren auswählen oder in der Symbolleiste von Android Studio Werkzeuge > Android > Projekt mit Gradle-Dateien synchronisieren auswählen.

Wenn Android Studio keine Fehler ausgibt, können Sie alle Funktionen verwenden, die wir am Anfang dieses Artikels aufgeführt haben, einschließlich Lambda-Ausdrücken!

Warum sind Lambda-Ausdrücke so wichtig?

Lambda-Ausdrücke waren mit Sicherheit die größte neue Funktion von Java 8 und können einen großen Einfluss auf die Menge an Boilerplate-Code haben, die Sie beim Erstellen so ziemlich jeder Android-App schreiben müssen.

Im Wesentlichen stellt ein Lambda-Ausdruck eine Funktion dar, die keiner Klasse angehört und die Sie problemlos weitergeben und bei Bedarf ausführen können.

Diese Funktion beseitigt die langjährige Frustration, die viele Android-Entwickler mit Java erlebt haben: Als objektorientierte Sprache war es immer schwieriger, Codeblöcke weiterzugeben, als es sein sollte. Wenn Sie beispielsweise einen neuen Thread erstellen und dann Code an diesen Thread übergeben möchten, müssen Sie normalerweise einen Thread mit einer anonymen Implementierung der Runnable-Schnittstelle instanziieren - das ist eine Menge Arbeit, nur um Code zu übergeben! Durch die einfache Übergabe einer Funktion an eine Methode können Lambda-Ausdrücke einige der häufigsten Aufgaben vereinfachen, die Sie als Android-Entwickler ausführen.

Lambda-Ausdrücke sind auch eine willkommene Ergänzung für alle Java-Entwickler, die ihre Programmierung funktionaler gestalten möchten. Vor Java 8 mussten Sie für das Codieren in einem funktionalen Stil zwangsläufig viel Code schreiben, aber jetzt, da Sie Funktionen mit Lambda-Ausdrücken weitergeben können, muss das Schreiben Ihres Java-Codes auf weniger objektorientierte Weise nicht mehr erforderlich sein eine Menge anonymer Klassen schreiben.

Wie erstelle ich einen Lambda-Ausdruck?

Sie erstellen einen Lambda-Ausdruck mit der folgenden Syntax:

Der Pfeiloperator ist ziemlich selbsterklärend, aber die Regeln für die Strukturierung des Arguments und des Ausdrucks des Lambda können je nach dem, was Sie erreichen möchten, variieren. Lassen Sie uns diese beiden Elemente genauer untersuchen.

Das Argument

Das Argument ist ein oder mehrere Parameter, die fast immer in Klammern stehen. Auch wenn Ihr Lambda-Ausdruck keine Parameter enthält, müssen Sie dennoch leere Klammern angeben, zum Beispiel:

Die Ausnahme von dieser Regel ist, wenn Ihre Methode einen einzelnen Parameter hat, dessen Typ abgeleitet ist. In diesem Fall können Sie die Klammern weglassen:

Sie können mehrere Parameter in Ihrem Argument verwenden, indem Sie jeden Parameter durch ein Komma trennen:

In Lambdas ist eine Typinferenz möglich, sodass Sie den Datentyp in der Regel in Ihrem Argument weglassen können. Wenn der Compiler den Datentyp jedoch nicht ableiten kann, müssen Sie den Typ vor Ihren Parametern hinzufügen:

Der Ausdruckskörper

Der Ausdruckskörper ist der Code, den Sie ausführen möchten. Dies kann ein einzelner Ausdruck oder mehrere Codezeilen sein. Wenn Sie mehrere Zeilen ausführen möchten, müssen Sie einen Anweisungsblock erstellen, indem Sie diesen Abschnitt Ihres Codes mit geschweiften Klammern umgeben:

Wenn Ihr Ausdruck einen Wert zurückgibt, muss er mit einer return-Anweisung zurückgegeben werden, zum Beispiel:

Verwenden von Lambda-Ausdrücken in Ihren Android-Apps

Jetzt haben wir einen Überblick über die verschiedenen Möglichkeiten, wie Sie einen Lambda-Ausdruck strukturieren können. Schauen wir uns einige der häufigsten Szenarien an, in denen Sie Lambda-Ausdrücke in Ihrer Android-Entwicklungsarbeit verwenden können.

Lambdas für die Ereignisbehandlung

Ihre typische Android-App muss in der Lage sein, auf eine Vielzahl von Benutzereingabeereignissen zu reagieren, und Lambda-Ausdrücke können die Handhabung dieses Ereignisses erheblich vereinfachen.

Im folgenden Code verwenden wir eine anonyme Klasse, um eine Instanz von onClickListener mit einer überschriebenen onClick-Methode zu erstellen. Wahrscheinlich haben Sie diese Art von Code unzählige Male geschrieben.

Durch Umschreiben des obigen Codes mit einem Lambda-Ausdruck können wir alle folgenden Elemente entfernen:

  • die Klasseninstanziierung: new View.OnClickListener()
  • Zugriffsmodifikator, Methodenname und Typ: public void onClick(View view)
  • und die Parametertypen, sodass Sie keine View view schreiben müssen

Dies bedeutet, dass wir genau dieselbe Funktionalität mit einer einzigen Zeile implementieren können:

Lambdas für Multithreading

Multithreading ist ein weiteres häufiges Szenario, in dem Lambda-Ausdrücke Ihnen beim Schreiben von sauberem Code helfen können. Standardmäßig verfügt Android über einen einzigen UI-Thread(Benutzeroberfläche), der für die Verarbeitung aller Benutzerinteraktionen, das Versenden von Ereignissen an die entsprechenden UI-Widgets und das Ändern der Benutzeroberfläche verantwortlich ist. Sobald Sie diesen UI-Thread mit lang laufenden oder intensiven Vorgängen blockieren, reagiert Ihre Anwendung nicht mehr und löst möglicherweise sogar den ANR-Dialog (Application Not Responding) von Android aus. Das Erstellen zusätzlicher Threads und das Zuweisen von Code zur Ausführung auf diesen Threads ist daher häufig ein wesentlicher Bestandteil der Android-Entwicklung.

Vor Java 8 mussten Sie zum Zuweisen von Code für die Ausführung in einem zusätzlichen Thread eine anonyme Klasse erstellen, die die Runnable-Schnittstelle implementiert:

Alternativ können Sie einen neuen Thread mit einer anonymen Implementierung der Runnable-Schnittstelle instanziieren:

Durch Ersetzen dieser anonymen Klasse durch einen Lambda-Ausdruck kann diese häufig ausgeführte Aufgabe viel präziser gestaltet werden:

Wenn Sie die RxJava- oder RxAndroid-Bibliothek verwenden, können Sie Lambda-Ausdrücke verwenden, um Observablen zu erstellen.

Hier erstellen wir ein einfaches Observable, das allen Observers die Hallo-Welt-Zeichenfolge sendet:

Mit einem Lambda-Ausdruck können Sie den gesamten Action1-Code durch eine einzige Zeile ersetzen:

Verwenden von Lambda-Ausdrücken in Ihrem Real-Life Code

Nachdem Sie die gesamte Theorie hinter einem neuen Funktion  gelesen haben, besteht die nächste Herausforderung darin, sich daran zu gewöhnen, dieses neue Funktion tatsächlich zu verwenden. Dies kann besonders bei Lambdas schwierig sein, die anstelle des bekannten Boilerplate-Codes verwendet werden sollen, da immer die Versuchung besteht, einfach auf das zurückzugreifen, was Sie wissen. 

Android Studio verfügt über einige Funktionen, die Ihnen dabei helfen können, vertrauten, aber klobigen Code durch glänzende neue Lambda-Ausdrücke zu ersetzen.

Die erste Funktion ist das Intent-Aktionsmenü von Android Studio, mit dem jede kompatible anonyme Klasse automatisch in den entsprechenden Lambda-Ausdruck konvertiert werden kann. Dies ist perfekt, wenn Sie sich nicht sicher sind, wie Sie einen bestimmten Code in einem Lambda-Format schreiben sollen: Schreiben Sie ihn einfach wie gewohnt und verwenden Sie dann die automatische Konvertierungsfunktion des Intent-Aktionsmenüs.

So konvertieren Sie eine anonyme Klasse automatisch in einen Lambda-Ausdruck:

  • Bewegen Sie den Mauszeiger über die anonyme Klasse, und Android Studio sollte einen Tooltip anzeigen, der Sie darüber informiert, dass dieser Codeabschnitt in einen Lambda-Ausdruck konvertiert werden kann.
  • Drücken Sie die Alt/Wahltaste Ihres Mac oder verwenden Sie die Alt-Eingabetaste, wenn Sie Windows- oder Linux-Benutzer sind.
  • Wählen Sie im Kontextmenü die Option Durch Lambda ersetzen.

Select Replace with lambda from the context menu that appearsSelect Replace with lambda from the context menu that appearsSelect Replace with lambda from the context menu that appears

Alternativ können Sie das Inspektionstool von Android Studio verwenden, um jede anonyme Klasse, die Sie möglicherweise durch einen Lambda-Ausdruck ersetzen könnten, in Ihrem gesamten Projekt zu kennzeichnen. Sie können dann entweder jede anonyme Klasse manuell umschreiben oder sich von der automatischen Konvertierungsfunktion von Android Studio zeigen lassen, wie es gemacht wird.

So markieren Sie jede anonyme Klasse, die Android Studio möglicherweise durch einen Lambda-Ausdruck ersetzen könnte:

  • Wählen Sie in der Android Studio-Symbolleiste Analysieren > Inspektion nach Namen ausführen.
  • Beginnen Sie im angezeigten Popup mit der Eingabe des anonymen Typs, der durch Lambda ersetzt werden kann, und wählen Sie diese Option aus, wenn sie im Dropdown-Menü angezeigt wird.

Select Anonymous type can be replaced with lambda from the Enter inspection name popupSelect Anonymous type can be replaced with lambda from the Enter inspection name popupSelect Anonymous type can be replaced with lambda from the Enter inspection name popup

  • Wählen Sie im folgenden Fenster Gesamtes Projekt aus, um jede anonyme Klasse in Ihrem Projekt zu kennzeichnen. Alternativ können Sie einzelne Module oder Dateien angeben, in denen Android Studio diese Überprüfung ausführen soll.
  • Klicken Sie OK.
  • Wählen Sie in der Android Studio-Symbolleiste Analysieren > Code überprüfen.

Der Bereich Inspektionsergebnisse sollte nun angezeigt werden und eine Liste aller anonymen Klassen anzeigen, die Sie durch einen Lambda-Ausdruck ersetzen können. Um eine anonyme Klasse genauer zu betrachten, doppelklicken Sie einfach im Prüfergebnisse-Fenster auf diese Klasse. Android Studio öffnet die Datei und führt Sie zu der genauen Zeile, die diese bestimmte anonyme Klasse enthält.

Um die aktuell ausgewählte anonyme Klasse durch einen Lambda-Ausdruck zu ersetzen, klicken Sie auf die Schaltfläche Durch Lambda ersetzen.

In the Inspection Results window select the Replace with lambda button In the Inspection Results window select the Replace with lambda button In the Inspection Results window select the Replace with lambda button

Wenn Android Studio das Fenster "Prüfergebnisse" nicht automatisch öffnet, können Sie es manuell starten, indem Sie in der Symbolleiste von Android Studio Ansicht > Werkzeugfenster > Prüfergebnisse auswählen. Wenn die Prüfergebnisse nicht im Untermenü von Werkzeug Windows angezeigt werden, müssen Sie möglicherweise zuerst in der Android Studio-Symbolleiste Analysieren > Code prüfen auswählen.

Testen von Lambda-Ausdrücken

Trotz der vielen Vorteile, die Lambda-Ausdrücke bieten, gibt es einen großen Nachteil, den Sie beachten sollten, bevor Sie sie Ihrem Code hinzufügen. Da Lambdas keinen Namen haben, können Sie sie nicht direkt aus Ihrem Testcode aufrufen. Das Hinzufügen einer großen Anzahl von Lambdas zu Ihrem Projekt kann das Testen erschweren.

Im Idealfall sollten Ihre Lambda-Ausdrücke zu einfach zu brechen sein, sodass es kein allzu großes Problem sein sollte, sie nicht einzeln testen zu können. Wenn Sie jedoch ein Lambda testen müssen, können Sie es immer wie eine private Methode behandeln und das Ergebnis in einer Einheit testen, anstatt das Lambda selbst. Alternativ können Sie den Lambda-Ausdruck in eine eigene Methode umgestalten, sodass Sie ihn direkt referenzieren und daher wie gewohnt testen können.

Schlussfolgerung

In diesem ersten Beitrag zu Java 8-Sprachfunktionen haben wir uns mit dem Einrichten Ihrer Android-Projekte zur Unterstützung von Java 8 und dem Reduzieren von Boilerplate-Code durch Ersetzen anonymer Klassen durch Lambda-Ausdrücke befasst.

Im nächsten Beitrag werde ich Ihnen zeigen, wie Sie noch mehr Code aus Ihren Android-Projekten entfernen können, indem Sie Lambda-Ausdrücke mit Methodenreferenzen kombinieren, und wie Sie Ihre Schnittstellen mit Standard- und statischen Schnittstellenmethoden erweitern können.

In der Zwischenzeit lesen Sie einige unserer anderen Beiträge zur Entwicklung von Android-Apps!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.