Wtyczka Androida do obsługi Gradle 4.0.0 (kwiecień 2020 r.)

Ta wersja wtyczki na Androida wymaga:

4.0.1 (lipiec 2020 r.)

Ta drobna aktualizacja zapewnia zgodność z nowymi domyślnymi ustawieniami i funkcjami widoczności pakietów w Androidzie 11.

W poprzednich wersjach Androida można było wyświetlić listę wszystkich aplikacji zainstalowanych na urządzeniu. Od Androida 11 (poziom interfejsu API 30) aplikacje domyślnie mają dostęp tylko do filtrowanej listy zainstalowanych pakietów. Aby zobaczyć szerszą listę aplikacji w systemie, musisz teraz dodać element <queries> do pliku manifestu Androida aplikacji lub biblioteki.

Wtyczka Androida do obsługi Gradle w wersji 4.1 lub nowszej jest już zgodna z nową deklaracją <queries>. Starsze wersje jej nie obsługują. Jeśli dodasz element <queries> albo zaczniesz polegać na bibliotece lub pakiecie SDK obsługującym kierowanie na Androida 11, podczas tworzenia aplikacji mogą wystąpić błędy scalania plików manifestu.

Aby go rozwiązać, publikujemy zestaw poprawek do AGP 3.3 i nowszych. Jeśli używasz starszej wersji AGP, uaktualnij do jednej z tych wersji:

Jeśli używasz
wersji AGP...
...przejdź na:
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

Więcej informacji o tej nowej funkcji znajdziesz w artykule o widoczności pakietów w Androidzie 11.

Nowe funkcje

Ta wersja wtyczki Androida do obsługi Gradle zawiera te nowe funkcje.

Obsługa Analizatora kompilacji Android Studio

Okno Analizator kompilacji ułatwia zrozumienie i diagnozowanie problemów z procesem kompilacji, takich jak wyłączone optymalizacje czy nieprawidłowo skonfigurowane zadania. Ta funkcja jest dostępna w Android Studio w wersji 4.0 lub nowszej z wtyczką Androida do obsługi Gradle w wersji 4.0.0 lub nowszej. Okno Analizator kompilacji w Android Studio możesz otworzyć w ten sposób:

  1. Jeśli nie masz jeszcze aplikacji, utwórz ją. W tym celu wybierz Kompilacja > Utwórz projekt z paska menu.
  2. Na pasku menu kliknij Widok > Okna narzędzi > Kompilacja.
  3. W oknie kompilacji otwórz okno Analizator kompilacji na jeden z tych sposobów:
    • Gdy Android Studio zakończy tworzenie projektu, kliknij kartę Analizator kompilacji.
    • Gdy Android Studio ukończy tworzenie projektu, kliknij link po prawej stronie okna Dane wyjściowe kompilacji.

Okno Analizator kompilacji zawiera drzewo po lewej stronie, w którym znajdują się możliwe problemy z kompilacjami. Możesz sprawdzić i kliknąć każdy problem, aby zapoznać się z jego szczegółami w panelu po prawej stronie. Gdy Android Studio analizuje kompilację, oblicza zbiór zadań, które określają czas trwania kompilacji, i udostępnia wizualizację, która pomaga zrozumieć wpływ każdego z tych zadań. Szczegółowe informacje o ostrzeżeniach możesz też uzyskać, rozwijając węzeł Ostrzeżenia.

Więcej informacji znajdziesz w artykule na temat rozpoznawania regresji szybkości kompilacji.

Odładowanie biblioteki Java 8 w wersjach D8 i R8

Wtyczka Androida do obsługi Gradle obejmuje teraz obsługę wielu interfejsów API w języku Java 8, nie wymagając przy tym minimalnego poziomu interfejsu API dla aplikacji.

Dzięki procesowi deugarowaniu kompilator D8 w Android Studio w wersji 3.0 i nowszych zapewnił już istotną obsługę funkcji języka Java 8 (takich jak wyrażenia lambda, domyślne metody interfejsu, możliwość wypróbowania zasobów itp.). W Android Studio 4.0 mechanizm usuwania odblasków został rozszerzony o możliwość użycia interfejsów API w języku Java. Oznacza to, że w aplikacjach obsługujących starsze wersje Androida możesz teraz korzystać z interfejsów API w standardowych językach, które były dostępne tylko w najnowszych wersjach Androida (np. java.util.streams).

Następujący zestaw interfejsów API jest obsługiwany w tej wersji:

  • Strumienie sekwencyjne (java.util.stream)
  • Podzbiór: java.time
  • java.util.function
  • Ostatnio dodane do: java.util.{Map,Collection,Comparator}
  • Opcjonalne (java.util.Optional, java.util.OptionalInt i java.util.OptionalDouble) oraz kilka innych nowych klas, które są przydatne przy powyższych interfejsach API
  • Poprawki do java.util.concurrent.atomic (nowe metody w AtomicInteger, AtomicLong i AtomicReference)
  • ConcurrentHashMap (z poprawkami błędów w Androidzie 5.0)

Aby obsługiwać te interfejsy API języka, D8 kompiluje oddzielny plik DEX biblioteki, który zawiera implementację brakujących interfejsów API i umieszcza ją w Twojej aplikacji. Proces odpalania przepisuje kod aplikacji tak, aby używał tej biblioteki w czasie działania.

Aby włączyć obsługę tych interfejsów API języka, umieść ten kod w pliku build.gradle modułu aplikacji:

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") }

Pamiętaj, że może być też konieczne umieszczenie tego fragmentu kodu w pliku build.gradle modułu biblioteki, jeśli

  • Testy z instrumentacją w module biblioteki wykorzystują te interfejsy API (bezpośrednio lub przez moduł biblioteki albo jego zależności). W ten sposób dostarczasz brakujące interfejsy API do instrumentowanego testowego pakietu APK.

  • Chcesz uruchomić narzędzie Lint w module biblioteki z osobna. Ma to pomóc w rozpoznawaniu prawidłowego użycia interfejsów API języka i unikaniu zgłaszania fałszywych ostrzeżeń.

Nowe opcje włączania i wyłączania funkcji kompilacji

Wtyczka Androida do obsługi Gradle w wersji 4.0.0 wprowadza nowy sposób kontrolowania funkcji kompilacji, które chcesz włączać i wyłączać, np. View Binding i Data Binding. Dodane nowe funkcje będą domyślnie wyłączone. Następnie możesz użyć bloku buildFeatures, aby włączyć tylko potrzebne funkcje. Pomaga to zoptymalizować wydajność kompilacji w projekcie. Opcje dla każdego modułu możesz ustawić w pliku build.gradle na poziomie modułu w ten sposób:

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
  }
}

Możesz też określić domyślne ustawienie tych funkcji we wszystkich modułach w projekcie, umieszczając w pliku gradle.properties projektu co najmniej jeden z tych elementów, jak pokazano poniżej. Pamiętaj, że nadal możesz użyć bloku buildFeatures w pliku build.gradle na poziomie modułu, aby zastąpić te domyślne ustawienia całego projektu.

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

Zależności funkcja-funkcja

W poprzednich wersjach wtyczki Androida do obsługi Gradle wszystkie moduły funkcji mogły zależeć tylko od podstawowego modułu aplikacji. Podczas korzystania z wtyczki Androida do obsługi Gradle w wersji 4.0.0 możesz teraz dodać moduł funkcji zależny od innego modułu funkcji. Oznacza to, że funkcja :video może zależeć od funkcji :camera, która zależy od modułu podstawowego, jak widać na ilustracji poniżej.

Funkcja dotycząca zależności funkcji

Moduł funkcji :video zależy od funkcji :camera, która zależy od podstawowego modułu :app.

Oznacza to, że gdy aplikacja prosi o pobranie modułu funkcji, pobiera też inne, od nich zależne moduły. Po utworzeniu modułów funkcji aplikacji możesz zadeklarować zależność funkcji od funkcji w pliku build.gradle modułu. Na przykład moduł :video deklaruje zależność od :camera w ten sposób:

// 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"))
    ...
}

Dodatkowo włącz funkcję zależności funkcji od funkcji w Android Studio (aby obsługiwać ją na przykład podczas edytowania konfiguracji uruchamiania), klikając Pomoc > Edytuj niestandardowe opcje maszyny wirtualnej na pasku menu i dodając te informacje:

-Drundebug.feature.on.feature=true

Metadane zależności

Gdy tworzysz aplikację za pomocą wtyczki Androida do obsługi Gradle w wersji 4.0.0 lub nowszej, wtyczka zawiera metadane opisujące zależności skompilowane w aplikację. Podczas przesyłania aplikacji Konsola Play sprawdza te metadane, aby zapewnić Ci te korzyści:

  • Otrzymuj alerty o znanych problemach z pakietami SDK i zależnościami, z których korzysta Twoja aplikacja
  • otrzymywać opinie pomagające w rozwiązaniu tych problemów;

Dane są kompresowane, szyfrowane kluczem podpisywania Google Play i przechowywane w bloku podpisywania aplikacji do publikacji. Możesz jednak samodzielnie sprawdzić metadane w lokalnych pośrednich plikach kompilacji w tym katalogu: <project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt.

Jeśli nie chcesz udostępniać tych informacji, możesz z nich zrezygnować, dodając ten fragment do pliku build.gradle modułu:

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
  }
}

Importuj biblioteki natywne z zależności AAR

Możesz teraz importować biblioteki C/C++ z zależności AAR aplikacji. Gdy wykonasz opisane poniżej czynności konfiguracyjne, Gradle automatycznie udostępni te biblioteki natywne do użycia z zewnętrznym natywnym systemem kompilacji, np. CMake. Pamiętaj, że Gradle udostępnia tylko te biblioteki w Twojej kompilacji. Nadal musisz skonfigurować skrypty kompilacji, aby z nich korzystać.

Biblioteki są eksportowane w formacie pakietu Prefab.

Każda zależność może ujawniać maksymalnie 1 pakiet Prefab, który składa się z 1 lub większej liczby modułów. Moduł Prefab to pojedyncza biblioteka, która może być biblioteką współdzieloną, statyczną lub biblioteką tylko z nagłówkiem.

Zwykle nazwa pakietu jest zgodna z nazwą artefaktu Maven, a nazwa modułu jest taka sama jak nazwa biblioteki, ale nie zawsze tak jest. Ponieważ musisz znać nazwy pakietów i modułów bibliotek, być może trzeba będzie sprawdzić te nazwy w dokumentacji zależności.

Skonfiguruj zewnętrzny system kompilacji natywnych

Aby dowiedzieć się, co musisz zrobić, wykonaj te czynności dotyczące zewnętrznego systemu kompilacji natywnych, którego zamierzasz używać.

Każda zależności AAR aplikacji obejmująca kod natywny ujawnia plik Android.mk, który należy zaimportować do projektu ndk-build. Importujesz ten plik za pomocą polecenia import&endash;module, które przeszukuje ścieżki podane przez Ciebie przy użyciu właściwości import&endash;add&endash;path w projekcie ndk-build. Jeśli na przykład Twoja aplikacja definiuje język libapp.so i używa narzędzia curl, w pliku Android.mk musisz umieścić ten fragment:

  1. W przypadku CMake:

    add_library(app SHARED app.cpp)

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

  2. 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)

Zależności natywne zawarte w AAR są udostępniane w projekcie CMake za pomocą zmiennej CCREATE_FIND_ROOT_PATH{: .external}. Ta wartość będzie ustawiana automatycznie przez Gradle przy wywołaniu CMake, więc jeśli Twój system kompilacji zmieni tę zmienną, nie dodawaj jej do niej, tylko ją przypisz.

Każda zależność ujawnia pakiet config-file{: .external} w kompilacji CMake, którą można zaimportować za pomocą polecenia find_package{: .external}. To polecenie wyszukuje pakiety config-file, które pasują do podanej nazwy i wersji pakietu, oraz ujawnia docelowe elementy zdefiniowane do użycia w kompilacji. Jeśli na przykład Twoja aplikacja definiuje libapp.so i używa narzędzia curl, w pliku CMakeLists.txt musisz umieścić ten fragment:


add_library(app SHARED app.cpp)

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

Możesz teraz określić #include "curl/curl.h" w app.cpp. Gdy tworzysz projekt, zewnętrzny system kompilacji automatycznie łączy libapp.so z elementem libcurl.so i pakiety libcurl.so w pliku APK lub pakiecie aplikacji. Więcej informacji znajdziesz w tym przykładzie {:.external}.

Zmiany w działaniu

Podczas korzystania z tej wersji wtyczki możesz zauważyć opisane poniżej zmiany w działaniu.

Aktualizacje konfiguracji podpisywania w wersji 1 lub 2

Działanie konfiguracji podpisywania aplikacji w bloku signingConfig wygląda tak:

Podpisywanie w wersji 1

  • Jeśli zasada v1SigningEnabled jest wyraźnie włączona, AGP wykonuje podpisywanie aplikacji w wersji 1.
  • Jeśli użytkownik wyłączy interfejs v1SigningEnabled, podpisywanie aplikacji w wersji 1 nie jest wykonywane.
  • Jeśli użytkownik nie włączył podpisywania w wersji 1, może ono zostać automatycznie wyłączone za pomocą tych zasad: minSdk i targetSdk.

Podpisywanie w wersji 2

  • Jeśli zasada v2SigningEnabled jest wyraźnie włączona, AGP wykonuje podpisywanie aplikacji w wersji 2.
  • Jeśli użytkownik wyłączy interfejs v2SigningEnabled, podpisywanie aplikacji w wersji 2 nie jest wykonywane.
  • Jeśli użytkownik nie włączył podpisywania w wersji 2, może ono zostać automatycznie wyłączone za pomocą zasady targetSdk.

Te zmiany pozwalają AGP optymalizować kompilacje przez wyłączenie mechanizmu podpisywania w zależności od tego, czy użytkownik jawnie włączył te flagi. Przed tą wersją możliwe było wyłączenie funkcji v1Signing, nawet jeśli jest ona wyraźnie włączona, co mogło być mylące.

Usunięto wtyczki feature i instantapp Androida do obsługi Gradle

Wtyczka Androida do obsługi Gradle w wersji 3.6.0 wycofała wtyczkę funkcji (com.android.feature) i aplikację błyskawiczną (com.android.instantapp). Zamiast niej do tworzenia i pakowania aplikacji błyskawicznych za pomocą pakietów Android App Bundle można było korzystać z wtyczki funkcji dynamicznych (com.android.dynamic-feature).

We wtyczce Androida do obsługi Gradle w wersji 4.0.0 lub nowszej te wycofane wtyczki są całkowicie usunięte. Aby użyć najnowszej wtyczki Androida do obsługi Gradle, musisz przeprowadzić migrację aplikacji błyskawicznej tak, aby obsługiwała pakiety Android App Bundle. Dzięki migracji aplikacji błyskawicznych możesz wykorzystać zalety pakietów aplikacji i uprościć modułowy projekt swojej aplikacji.

Uwaga: aby otwierać projekty, które wykorzystują usunięte wtyczki w Androidzie Studio w wersji 4.0 lub nowszej, muszą korzystać z wtyczki Androida do obsługi Gradle w wersji 3.6.0 lub starszej.

Usunięto osobną funkcję przetwarzania adnotacji

Usunęliśmy możliwość rozdzielania przetwarzania adnotacji na dedykowane zadanie. Ta opcja była używana do utrzymywania przyrostowej kompilacji w Javie w przypadku, gdy w projektach wyłącznie Java używane są procesory adnotacji nieprzyrostowe. Została włączona przez ustawienie android.enableSeparateAnnotationProcessing na true w pliku gradle.properties, które już nie działa.

Zamiast tego zacznij korzystać z przyrostowych procesorów adnotacji, aby zwiększyć wydajność kompilacji.

Parametr includeCompileClasspath został wycofany

Wtyczka Androida do obsługi Gradle nie sprawdza już ani nie uwzględnia procesorów adnotacji zadeklarowanych w ścieżce klasy kompilacji, a właściwość DSL annotationProcessorOptions.includeCompileClasspath już nie działa. Jeśli w ścieżce klasy kompilowania uwzględnisz procesory adnotacji, może pojawić się ten błąd:

Error: Annotation processors must be explicitly declared now.

Aby rozwiązać ten problem, musisz uwzględnić procesory adnotacji w plikach build.gradle za pomocą konfiguracji zależności annotationProcessor. Więcej informacji znajdziesz w artykule Dodawanie procesorów adnotacji.

Automatyczne tworzenie gotowych zależności używanych przez CMake

Wcześniejsze wersje wtyczki Androida do obsługi Gradle wymagały jawnego spakowania gotowych bibliotek używanych przez zewnętrzną kompilację natywną CMake przy użyciu jniLibs. Możesz umieścić biblioteki w katalogu src/main/jniLibs swojego modułu lub w innym katalogu skonfigurowanym w pliku build.gradle:

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"))
  }
}

W przypadku wtyczki Androida do obsługi Gradle w wersji 4.0 powyższa konfiguracja nie jest już potrzebna i spowoduje błąd kompilacji:

* 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'

Zewnętrzna kompilacja natywna automatycznie pakuje te biblioteki, więc jawne spakowanie biblioteki z atrybutem jniLibs skutkuje duplikatem. Aby uniknąć błędu kompilacji, przenieś gotową bibliotekę do lokalizacji poza jniLibs lub usuń konfigurację jniLibs z pliku build.gradle.

Znane problemy

W tej sekcji opisano znane problemy, które występują we wtyczce Androida do obsługi Gradle w wersji 4.0.0.

Warunek rasy w mechanizmie instancji roboczej Gradle

Zmiany w wtyczce Androida do obsługi Gradle w wersji 4.0 mogą aktywować warunek wyścigu w Gradle podczas działania z &endash;&endash;no&endash;daemon i wersjami Gradle w wersji 6.3 lub starszej, co może powodować zawieszanie kompilacji po zakończeniu kompilacji.

Ten problem zostanie rozwiązany w Gradle 6.4.