Android Gradle-Plug-in 4.0.0 (April 2020)

Für diese Version des Android-Plug-ins ist Folgendes erforderlich:

4.0.1 (Juli 2020)

Dieses kleine Update unterstützt die Kompatibilität mit neuen Standardeinstellungen und -funktionen für die Paketsichtbarkeit in Android 11.

In früheren Android-Versionen war es möglich, eine Liste aller auf einem Gerät installierten Apps anzuzeigen. Ab Android 11 (API-Level 30) haben Apps standardmäßig nur Zugriff auf eine gefilterte Liste installierter Pakete. Wenn du eine umfassendere Liste der Apps im System sehen möchtest, musst du dem Android-Manifest deiner App oder Mediathek jetzt ein <queries>-Element hinzufügen.

Das Android-Gradle-Plug-in 4.1 und höher ist bereits mit der neuen <queries>-Deklaration kompatibel. Ältere Versionen sind jedoch nicht kompatibel. Wenn du das <queries>-Element hinzufügst oder eine Bibliothek oder ein SDK nutzt, das die Ausrichtung auf Android 11 unterstützt, können beim Erstellen deiner App Manifest-Zusammenführungsfehler auftreten.

Um dieses Problem zu beheben, veröffentlichen wir eine Reihe von Patches für AGP 3.3 und höher. Wenn Sie eine ältere Version von AGP verwenden, führen Sie ein Upgrade auf eine der folgenden Versionen durch:

Wenn Sie die
AGP-Version verwenden...
...führen Sie ein Upgrade auf:
4,0.* 4.0.1
3,6.* 3.6.4
3,5.* 3.5.4
3,4.* 3.4.3
3.3.* 3.3.3

Weitere Informationen zu dieser neuen Funktion findest du unter Paketsichtbarkeit in Android 11.

Neue Funktionen

Diese Version des Android-Gradle-Plug-ins enthält die folgenden neuen Funktionen.

Unterstützung für Android Studio Build Analyzer

Im Fenster Build Analyzer können Sie Probleme im Build-Prozess, z. B. deaktivierte Optimierungen und falsch konfigurierte Aufgaben, besser verstehen und diagnostizieren. Diese Funktion ist verfügbar, wenn Sie Android Studio 4.0 und höher mit dem Android-Gradle-Plug-in 4.0.0 und höher verwenden. So öffnen Sie das Fenster Build Analyzer in Android Studio:

  1. Erstellen Sie Ihre Anwendung, falls Sie dies noch nicht getan haben. Wählen Sie dazu in der Menüleiste Build > Make Project (Erstellen > Projekt erstellen) aus.
  2. Wählen Sie in der Menüleiste Ansicht > Toolfenster > Erstellen aus.
  3. Öffnen Sie im Fenster Build das Fenster Build Analyzer auf eine der folgenden Arten:
    • Nachdem Android Studio die Erstellung Ihres Projekts abgeschlossen hat, klicken Sie auf den Tab Build Analyzer.
    • Nachdem Android Studio die Erstellung Ihres Projekts abgeschlossen hat, klicken Sie auf den Link rechts im Fenster Build-Ausgabe.

Im Fenster Build Analyzer werden mögliche Build-Probleme in einer Baumstruktur auf der linken Seite organisiert. Sie können jedes Problem im Bereich rechts prüfen und darauf klicken, um die Details zu untersuchen. Wenn Android Studio Ihren Build analysiert, werden die Aufgaben berechnet, die die Build-Dauer bestimmt haben. Außerdem wird eine Visualisierung bereitgestellt, damit Sie die Auswirkungen dieser Aufgaben besser nachvollziehen können. Wenn Sie den Knoten Warnungen maximieren, können Sie auch Details zu Warnungen abrufen.

Weitere Informationen finden Sie unter Regressionen der Build-Geschwindigkeit identifizieren.

Java 8-Bibliotheks-Entsugaring in D8 und R8

Das Android-Gradle-Plug-in unterstützt jetzt verschiedene Java 8-Sprach-APIs, ohne dass Sie ein Mindest-API-Level für Ihre App benötigen.

Durch einen Prozess namens Desugaring bot der DEX-Compiler D8 in Android Studio 3.0 und höher bereits umfassende Unterstützung für die Java 8-Sprachfunktionen (z. B. Lambda-Ausdrücke, Standardoberflächenmethoden, Tests mit Ressourcen und mehr). In Android Studio 4.0 wurde die Desugaring-Engine so erweitert, dass sie auch Java-Sprach-APIs verwenden kann. Das bedeutet, dass du jetzt APIs in Standardsprachen, die nur in den aktuellen Android-Releases (z. B. java.util.streams) verfügbar waren, in Apps einbinden kannst, die ältere Android-Versionen unterstützen.

Die folgenden APIs werden in dieser Version unterstützt:

  • Sequenzielle Streams (java.util.stream)
  • Eine Untergruppe von java.time
  • java.util.function
  • Kürzlich hinzugefügt: java.util.{Map,Collection,Comparator}
  • Optionale Werte (java.util.Optional, java.util.OptionalInt und java.util.OptionalDouble) und einige andere neue Klassen, die für die oben genannten APIs nützlich sind
  • Einige Ergänzungen von java.util.concurrent.atomic (neue Methoden für AtomicInteger, AtomicLong und AtomicReference)
  • ConcurrentHashMap (mit Fehlerkorrekturen für Android 5.0)

Zur Unterstützung dieser Sprach-APIs kompiliert D8 eine separate Bibliotheks-DEX-Datei, die eine Implementierung der fehlenden APIs enthält, und fügt sie in Ihre Anwendung ein. Beim Entsugaring-Prozess wird der Code Ihrer Anwendung so umgeschrieben, dass stattdessen diese Bibliothek zur Laufzeit verwendet wird.

Damit diese Sprach-APIs unterstützt werden, nehmen Sie Folgendes in die Datei build.gradle Ihres App-Moduls auf:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4' }

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled = true
  }

compileOptions { // Flag to enable support for the new language APIs isCoreLibraryDesugaringEnabled = true // Sets Java compatibility to Java 8 sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.4") }

Möglicherweise müssen Sie das obige Code-Snippet auch in die Datei build.gradle eines Bibliotheksmoduls einfügen, wenn

  • Die instrumentierten Tests des Bibliotheksmoduls verwenden diese Sprach-APIs (entweder direkt oder über das Bibliotheksmodul oder dessen Abhängigkeiten). Dadurch werden die fehlenden APIs für dein instrumentiertes Test-APK bereitgestellt.

  • Sie möchten Lint isoliert für das Bibliotheksmodul ausführen. So kann Lint gültige Verwendungen der Language APIs erkennen und vermeiden, falsche Warnungen zu melden.

Neue Optionen zum Aktivieren oder Deaktivieren von Build-Features

Mit dem Android-Gradle-Plug-in 4.0.0 lässt sich steuern, welche Build-Funktionen aktiviert und deaktiviert werden sollen, z. B. Ansichtsbindung und Datenbindung. Wenn neue Funktionen hinzugefügt werden, werden diese standardmäßig deaktiviert. Anschließend können Sie den buildFeatures-Block verwenden, um nur die gewünschten Features zu aktivieren und die Build-Leistung für Ihr Projekt zu optimieren. Sie können die Optionen für jedes Modul in der Datei build.gradle auf Modulebene so festlegen:

android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}
android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}

Sie können auch die Standardeinstellung für diese Features für alle Module eines Projekts festlegen. Dazu nehmen Sie eines oder mehrere der folgenden Elemente in die gradle.properties-Datei Ihres Projekts auf (siehe unten). Hinweis: Sie können den Block buildFeatures in der Datei build.gradle auf Modulebene weiterhin verwenden, um diese projektweiten Standardeinstellungen zu überschreiben.

android.defaults.buildfeatures.buildconfig=true
android.defaults.buildfeatures.aidl=true
android.defaults.buildfeatures.renderscript=true
android.defaults.buildfeatures.resvalues=true
android.defaults.buildfeatures.shaders=true

Feature-on-Feature-Abhängigkeiten

In früheren Versionen des Android-Gradle-Plug-ins können alle Funktionsmodule nur vom Basismodul der App abhängen. Wenn Sie das Android-Gradle-Plug-in 4.0.0 verwenden, können Sie jetzt ein Feature-Modul einbinden, das von einem anderen Feature-Modul abhängt. Das heißt, ein :video-Feature kann von dem :camera-Feature abhängen, das vom Basismodul abhängt, wie in der folgenden Abbildung dargestellt.

Feature für Funktionsabhängigkeiten

Das Featuremodul :video hängt vom Feature :camera ab, das vom Basismodul :app abhängt.

Wenn Ihre Anwendung den Download eines Feature-Moduls anfordert, lädt sie also auch andere Feature-Module herunter, von denen sie abhängig ist. Nachdem du Featuremodule für deine App erstellt hast, kannst du eine Feature-on-Feature-Abhängigkeit in der Datei build.gradle des Moduls deklarieren. Das Modul :video deklariert beispielsweise eine Abhängigkeit von :camera so:

// In the build.gradle file of the ':video' module.
dependencies {
  // All feature modules must declare a dependency
  // on the base module.
  implementation project(':app')
  // Declares that this module also depends on the 'camera'
  // feature module.
  implementation project(':camera')
  ...
}
// In the build.gradle file of the ':video' module.
dependencies {
    // All feature modules must declare a dependency
    // on the base module.
    implementation(project(":app"))
    // Declares that this module also depends on the 'camera'
    // feature module.
    implementation(project(":camera"))
    ...
}

Außerdem sollten Sie die Feature-on-Feature-Abhängigkeit in Android Studio aktivieren, um die Funktion beispielsweise beim Bearbeiten der Ausführungskonfiguration zu unterstützen. Klicken Sie dazu in der Menüleiste auf Hilfe > Benutzerdefinierte VM-Optionen bearbeiten und fügen Sie Folgendes hinzu:

-Drundebug.feature.on.feature=true

Abhängigkeitsmetadaten

Wenn Sie Ihre App mit dem Android-Gradle-Plug-in 4.0.0 und höher erstellen, enthält das Plug-in Metadaten, die die Abhängigkeiten beschreiben, die in Ihrer App kompiliert werden. Beim Hochladen Ihrer App prüft die Play Console diese Metadaten, um Ihnen folgende Vorteile zu bieten:

  • Du kannst dich über bekannte Probleme mit SDKs und Abhängigkeiten deiner App benachrichtigen lassen
  • Umsetzbares Feedback zur Lösung dieser Probleme erhalten

Die Daten werden komprimiert, mit einem Google Play-Signaturschlüssel verschlüsselt und im Signaturblock der Release-App gespeichert. Sie können die Metadaten jedoch selbst in den lokalen Zwischen-Build-Dateien im folgenden Verzeichnis einsehen: <project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt.

Wenn du diese Informationen nicht teilen möchtest, kannst du dies widerrufen, indem du Folgendes in die build.gradle-Datei deines Moduls einfügst:

android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}
android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}

Native Bibliotheken aus AAR-Abhängigkeiten importieren

Sie können jetzt C/C++-Bibliotheken aus den AAR-Abhängigkeiten Ihrer App importieren. Wenn du die unten beschriebenen Konfigurationsschritte ausführst, stellt Gradle diese nativen Bibliotheken automatisch zur Verwendung mit deinem externen nativen Build-System wie CMake zur Verfügung. Hinweis: Gradle stellt diese Bibliotheken nur für Ihren Build zur Verfügung. Sie müssen Ihre Build-Skripts aber weiter konfigurieren, um sie zu verwenden.

Bibliotheken werden im Prefab-Paketformat exportiert.

Jede Abhängigkeit kann höchstens ein Fertigpaket zur Verfügung stellen, das ein oder mehrere Module umfasst. Ein Prefab-Modul ist eine einzelne Bibliothek, die entweder eine gemeinsam genutzte, statische oder nur Header-Bibliothek sein kann.

In der Regel stimmt der Paketname mit dem Namen des Maven-Artefakts und der Modulname mit dem Namen der Bibliothek überein. Dies ist jedoch nicht immer wahr. Da Sie den Paket- und Modulnamen der Bibliotheken kennen müssen, finden Sie diese Namen möglicherweise in der Dokumentation der Abhängigkeit.

Externes natives Build-System konfigurieren

Führen Sie die folgenden Schritte für das externe native Build-System aus, das Sie verwenden möchten.

Jede AAR-Abhängigkeit Ihrer Anwendung, die nativen Code enthält, macht eine Android.mk-Datei verfügbar, die Sie in Ihr ndk-build-Projekt importieren müssen. Sie importieren diese Datei mit dem Befehl import&endash;module. Dieser durchsucht die von Ihnen mit dem Attribut import&endash;add&endash;path im Projekt „ndk-build“ angegebenen Pfade. Wenn Ihre App beispielsweise libapp.so definiert und curl verwendet, sollten Sie Folgendes in die Datei „Android.mk“ aufnehmen:

  1. Für CMake:

    add_library(app SHARED app.cpp)

    # Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

  2. Für ndk-build:

    include $(CLEAR_VARS)
    LOCAL_MODULE := libapp
    LOCAL_SRC_FILES := app.cpp
    # Link libcurl from the curl AAR.
    LOCAL_SHARED_LIBRARIES := curl
    include $(BUILD_SHARED_LIBRARY)

    # If you don't expect that your project will be built using versions of the NDK # older than r21, you can omit this block. ifneq ($(call ndk-major-at-least,21),true) $(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH)) endif

    # Import all modules that are included in the curl AAR. $(call import-module,prefab/curl)

Native Abhängigkeiten, die in einem AAE enthalten sind, werden über die Variable CMake_FIND_ROOT_PATH{: .external} für Ihr CMake-Projekt freigegeben. Dieser Wert wird von Gradle automatisch festgelegt, wenn CMake aufgerufen wird. Wenn Ihr Build-System diese Variable ändert, sollten Sie sie also anhängen, anstatt sie zuzuweisen.

Jede Abhängigkeit stellt ein config-file-Paket{: .external} für Ihren CMake-Build bereit, das Sie mit dem Befehl find_package{: .external} importieren. Dieser Befehl sucht nach Konfigurationsdateipaketen, die dem angegebenen Paketnamen und der angegebenen Paketversion entsprechen, und macht die Ziele verfügbar, die zur Verwendung in Ihrem Build definiert wurden. Wenn Ihre Anwendung beispielsweise libapp.so definiert und curl verwendet, sollten Sie Folgendes in die Datei CMakeLists.txt aufnehmen:


add_library(app SHARED app.cpp)

# Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

Sie können jetzt #include "curl/curl.h" in app.cpp angeben. Wenn du dein Projekt erstellst, verknüpft dein externes natives Build-System libapp.so automatisch mit libcurl.so und Paketen libcurl.so im APK oder App Bundle. Weitere Informationen finden Sie im curl-Fertigbeispiel{:.external}.

Änderungen des Verhaltens

Wenn Sie diese Version des Plug-ins verwenden, kann es zu folgenden Verhaltensänderungen kommen.

Aktualisierungen der Signaturkonfiguration von v1/v2

Das Verhalten für App-Signaturkonfigurationen im Block signingConfig hat sich so geändert:

v1-Signatur

  • Wenn v1SigningEnabled explizit aktiviert ist, führt AGP die v1-App-Signatur durch.
  • Wenn v1SigningEnabled explizit vom Nutzer deaktiviert wurde, wird die V1-Anwendungssignatur nicht ausgeführt.
  • Wenn der Nutzer die V1-Signatur nicht explizit aktiviert hat, kann sie anhand von minSdk und targetSdk automatisch deaktiviert werden.

v2-Signatur

  • Wenn v2SigningEnabled explizit aktiviert ist, führt AGP die V2-App-Signatur durch.
  • Wenn v2SigningEnabled explizit vom Nutzer deaktiviert wurde, wird die V2-Anwendungssignatur nicht ausgeführt.
  • Wenn der Nutzer die V2-Signatur nicht explizit aktiviert hat, kann sie anhand von targetSdk automatisch deaktiviert werden.

Durch diese Änderungen kann AGP Builds optimieren, indem der Signaturmechanismus je nachdem, ob der Nutzer diese Flags explizit aktiviert hat, deaktiviert wird. Vor dieser Version konnte v1Signing auch bei expliziter Aktivierung deaktiviert werden, was verwirrend war.

Android-Gradle-Plug-ins feature und instantapp wurden entfernt

Das Android-Gradle-Plug-in 3.6.0 hat das Feature-Plug-in (com.android.feature) und das Instant App-Plug-in (com.android.instantapp) eingestellt. Stattdessen wurde das Plug-in für dynamische Funktionen (com.android.dynamic-feature) verwendet, um deine Instant-Apps mit Android App Bundles zu erstellen und zu verpacken.

Ab Version 4.0.0 des Android-Gradle-Plug-ins wurden diese verworfenen Plug-ins vollständig entfernt. Damit Sie das neueste Android-Gradle-Plug-in verwenden können, müssen Sie also Ihre Instant App migrieren, damit sie Android App Bundles unterstützt. Durch die Migration Ihrer Instant-Apps können Sie die Vorteile von App Bundles nutzen und das modulare Design Ihrer App vereinfachen.

Hinweis: Zum Öffnen von Projekten, die die entfernten Plug-ins in Android Studio 4.0 und höher verwenden, muss das Projekt das Android Gradle-Plug-in 3.6.0 oder niedriger verwenden.

Separate Funktion für die Verarbeitung von Anmerkungen entfernt

Die Möglichkeit, die Verarbeitung von Anmerkungen in eine eigene Aufgabe zu unterteilen, wurde entfernt. Diese Option wurde verwendet, um die inkrementelle Java-Kompilierung beizubehalten, wenn nicht inkrementelle Annotationsprozessoren in reinen Java-Projekten verwendet wurden. Sie wurde aktiviert, indem android.enableSeparateAnnotationProcessing in der Datei gradle.properties auf true gesetzt wurde, da diese nicht mehr funktioniert.

Stattdessen sollten Sie zur Verwendung von inkrementellen Annotationsprozessoren migrieren, um die Build-Leistung zu verbessern.

includeCompileClasspath wurde eingestellt

Das Android-Gradle-Plug-in sucht nicht mehr nach Annotationsprozessoren, die Sie im Compile-Klassenpfad deklarieren, und enthält keine solchen Annotationen mehr. Außerdem hat das DSL-Attribut annotationProcessorOptions.includeCompileClasspath keine Auswirkungen mehr. Wenn Sie Annotationsprozessoren in den Kompilierungsklassenpfad aufnehmen, wird möglicherweise der folgende Fehler ausgegeben:

Error: Annotation processors must be explicitly declared now.

Um dieses Problem zu beheben, müssen Sie mithilfe der Abhängigkeitskonfiguration annotationProcessor Annotationsprozessoren in Ihre build.gradle-Dateien aufnehmen. Weitere Informationen finden Sie unter Annotationsprozessoren hinzufügen.

Automatische Paketerstellung für vordefinierte Abhängigkeiten, die von CMake verwendet werden

Bei früheren Versionen des Android-Gradle-Plug-ins mussten alle vordefinierten Bibliotheken, die von deinem externen nativen CMake-Build verwendet wurden, mithilfe von jniLibs explizit verpackt werden. Möglicherweise befinden sich Bibliotheken im Verzeichnis src/main/jniLibs Ihres Moduls oder in einem anderen Verzeichnis, das in der Datei build.gradle konfiguriert ist:

sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.srcDirs = ['libs']
  }
}
sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.setSrcDirs(listOf("libs"))
  }
}

Mit dem Android Gradle-Plug-in 4.0 ist die obige Konfiguration nicht mehr erforderlich und führt zu einem Build-Fehler:

* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
  > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
    > More than one file was found with OS independent path 'lib/x86/libprebuilt.so'

Der externe native Build verpackt diese Bibliotheken jetzt automatisch. Wenn die Bibliothek also explizit mit jniLibs verpackt wird, entsteht ein Duplikat. Verschieben Sie die vordefinierte Bibliothek an einen Speicherort außerhalb von jniLibs oder entfernen Sie die jniLibs-Konfiguration aus der Datei build.gradle, um den Build-Fehler zu vermeiden.

Bekannte Probleme

In diesem Abschnitt werden bekannte Probleme im Android-Gradle-Plug-in 4.0.0 beschrieben.

Race-Bedingung im Gradle-Worker-Mechanismus

Änderungen im Android-Gradle-Plug-in 4.0 können eine Race-Bedingung in Gradle auslösen, wenn sie mit &endash;&endash;no&endash;daemon und Versionen von Gradle 6.3 oder niedriger ausgeführt werden. Dadurch hängen Builds nach Abschluss des Builds auf.

Dieses Problem wird in Gradle 6.4 behoben.