Wtyczka Androida do obsługi Gradle w wersji 3.0.0 (październik 2017 r.)

Wtyczka Androida do obsługi Gradle w wersji 3.0.0 zawiera wiele zmian, które mają na celu rozwiązanie problemów z wydajnością w dużych projektach.

Na przykład w przykładowym projekcie szkieletowym z ok. 130 modułami i dużą liczbą zależności zewnętrznych (ale bez kodu ani zasobów) możesz zauważyć poprawę wydajności podobną do tej:

Wersja wtyczki Androida + wersja Gradle Wtyczka Androida 2.2.0 + Gradle 2.14.1 Wtyczka Androida 2.3.0 + Gradle 3.3 Wtyczka Androida 3.0.0 + Gradle 4.1
Konfiguracja (np. uruchomienie ./gradlew --help) ok. 2 min ok. 9 s ok.2,5 s
Zmiana 1 wiersza w Javie (zmiana implementacji) ok. 2 min 15 s ok. 29 s ok.6,4 s

Niektóre z tych zmian powodują przerwanie istniejących kompilacji. Dlatego przed użyciem nowej wtyczki warto zastanowić się, ile pracy będzie wymagać migracja projektu.

Jeśli nie zauważysz opisanych powyżej ulepszeń wydajności, prosimy o zgłoszenie błędu i dołączenie śladu kompilacji za pomocą narzędzia Gradle Profiler.

Ta wersja wtyczki Androida wymaga:

Wersja minimalna Wersja domyślna Uwagi
Gradle 4.1 4.1 Więcej informacji znajdziesz w artykule o aktualizowaniu Gradle.
Narzędzia do kompilacji pakietu SDK 26.0.2 26.0.2 Zainstaluj lub skonfiguruj narzędzia SDK do kompilacji. Dzięki tej aktualizacji nie musisz już określać wersji narzędzi do kompilacji – wtyczka domyślnie używa minimalnej wymaganej wersji. Możesz więc usunąć właściwość android.buildToolsVersion.

3.0.1 (listopad 2017 r.)

Jest to niewielka aktualizacja, która obsługuje Androida Studio 3.0.1 i zawiera ogólne poprawki błędów oraz ulepszenia wydajności.

Optymalizacje

  • Lepsza równoległość w projektach wielomodułowych dzięki szczegółowemu grafowi zadań.
  • Gdy wprowadzisz zmiany w zależności, Gradle wykonuje szybsze kompilacje, ponieważ nie kompiluje ponownie modułów, które nie mają dostępu do interfejsu API tej zależności. Powinieneś ograniczyć, które zależności udostępniają swoje interfejsy API innym modułom, używając nowych konfiguracji zależności Gradle: implementation, api, compileOnly, i runtimeOnly.
  • Szybsza kompilacja przyrostowa dzięki dexowaniu na poziomie klasy. Każda klasa jest teraz kompilowana do osobnych plików DEX, a tylko klasy, które są zmodyfikowane, są ponownie dexowane. Możesz też spodziewać się szybszych kompilacji aplikacji, które mają ustawioną wartość minSdkVersion na 20 lub niższą i używają starszej wersji multi-dex.
  • Szybsze kompilacje dzięki optymalizacji niektórych zadań, które używają danych z pamięci podręcznej. Aby skorzystać z tej optymalizacji, musisz najpierw włączyć pamięć podręczną kompilacji Gradle.
  • Ulepszone przyrostowe przetwarzanie zasobów za pomocą narzędzia AAPT2, które jest teraz domyślnie włączone. Jeśli podczas korzystania z AAPT2 wystąpią problemy, zgłoś błąd. Możesz też wyłączyć AAPT2, ustawiając android.enableAapt2=false w pliku gradle.properties i ponownie uruchamiając demona Gradle, wpisując w wierszu poleceń ./gradlew --stop.

Nowe funkcje

  • Zarządzanie zależnościami z uwzględnieniem wariantów. Podczas kompilowania określonego wariantu modułu wtyczka automatycznie dopasowuje warianty lokalnych zależności modułu biblioteki do wariantu kompilowanego modułu.
  • Zawiera nową wtyczkę modułu funkcji, która obsługuje aplikacje błyskawiczne na Androida i pakiet SDK do aplikacji błyskawicznych na Androida (możesz go pobrać za pomocą narzędzia SDK Manager). Więcej informacji o tworzeniu modułów funkcji za pomocą nowej wtyczki znajdziesz w artykule Struktura aplikacji błyskawicznej z wieloma funkcjami.
  • Wbudowana obsługa niektórych funkcji języka Java 8 i bibliotek Java 8. Jack jest teraz przestarzały i nie jest już wymagany, a aby korzystać z ulepszonej obsługi Javy 8 wbudowanej w domyślny łańcuch narzędzi, musisz najpierw wyłączyć Jacka. Więcej informacji znajdziesz w artykule Korzystanie z funkcji języka Java 8.
  • Dodano obsługę uruchamiania testów za pomocą Android Test Orchestrator, które umożliwia uruchamianie każdego testu aplikacji w osobnej instancji instrumentacji. Ponieważ każdy test jest uruchamiany w osobnej instancji instrumentacji, żaden stan współdzielony między testami nie obciąża procesora ani pamięci urządzenia. Nawet jeśli jeden test ulegnie awarii, spowoduje to tylko zamknięcie jego własnej instancji instrumentacji, więc pozostałe testy będą nadal działać.

    • Dodano testOptions.execution, aby określić, czy używać orkiestracji testów na urządzeniu. Jeśli chcesz używać narzędzia Android Test Orchestrator, musisz określić ANDROID_TEST_ORCHESTRATOR, jak pokazano poniżej. Domyślnie ta właściwość jest ustawiona na HOST, co wyłącza orkiestrację na urządzeniu i jest standardową metodą uruchamiania testów.

    Dynamiczny

            android {
              testOptions {
                execution 'ANDROID_TEST_ORCHESTRATOR'
              }
            }
            

    Kotlin

            android {
              testOptions {
                execution = "ANDROID_TEST_ORCHESTRATOR"
              }
            }
            
  • Nowa konfiguracja zależności androidTestUtil umożliwia zainstalowanie innego pliku APK z pomocnikiem testowym przed uruchomieniem testów z instrumentacją, np. Android Test Orchestrator:

    Dynamiczny

            dependencies {
              androidTestUtil 'com.android.support.test:orchestrator:1.0.0'
              ...
            }
            

    Kotlin

            dependencies {
              androidTestUtil("com.android.support.test:orchestrator:1.0.0")
              ...
            }
            
  • Dodano testOptions.unitTests.includeAndroidResources, aby obsługiwać testy jednostkowe, które wymagają zasobów Androida, np. Roboelectric. Gdy ustawisz tę właściwość na true, wtyczka przed uruchomieniem testów jednostkowych scali zasoby, komponenty i manifest. Testy mogą wtedy sprawdzać com/android/tools/test_config.properties w ścieżce klasy pod kątem tych kluczy:

    • android_merged_assets: ścieżka bezwzględna do scalonego katalogu zasobów.

      Uwaga: w przypadku modułów biblioteki scalone zasoby nie zawierają zasobów zależności (patrz problem #65550419).

    • android_merged_manifest: ścieżka bezwzględna do manifestu łączonego.

    • android_merged_resources: ścieżka bezwzględna do scalonego katalogu zasobów, który zawiera wszystkie zasoby z modułu i wszystkie jego zależności.

    • android_custom_package: nazwa pakietu końcowej klasy R. Jeśli dynamicznie modyfikujesz identyfikator aplikacji, ta nazwa pakietu może nie pasować do atrybutu package w manifeście aplikacji.

  • Obsługa czcionek jako zasobów (nowa funkcja wprowadzona w Androidzie 8.0 (poziom 26 interfejsu API))).
  • Obsługa plików APK specyficznych dla języka w pakiecie Android Instant Apps SDK w wersji 1.1 lub nowszej.
  • Możesz teraz zmienić katalog wyjściowy zewnętrznego projektu kompilacji natywnej, jak pokazano poniżej:

    Dynamiczny

            android {
                ...
                externalNativeBuild {
                    // For ndk-build, instead use the ndkBuild block.
                    cmake {
                        ...
                        // Specifies a relative path for outputs from external native
                        // builds. You can specify any path that's not a subdirectory
                        // of your project's temporary build/ directory.
                        buildStagingDirectory "./outputs/cmake"
                    }
                }
            }
            

    Kotlin

            android {
                ...
                externalNativeBuild {
                    // For ndk-build, instead use the ndkBuild block.
                    cmake {
                        ...
                        // Specifies a relative path for outputs from external native
                        // builds. You can specify any path that's not a subdirectory
                        // of your project's temporary build/ directory.
                        buildStagingDirectory = "./outputs/cmake"
                    }
                }
            }
            
  • Podczas kompilowania projektów natywnych w Android Studio możesz teraz używać CMake w wersji 3.7 lub nowszej.
  • Nowa konfiguracja zależności lintChecks umożliwia utworzenie pliku JAR, który definiuje niestandardowe reguły lintera, i spakowanie go do projektów AAR i APK.

    Niestandardowe reguły lintera muszą należeć do osobnego projektu, który generuje pojedynczy plik JAR i zawiera tylko compileOnly zależności. Inne moduły aplikacji i biblioteki mogą wtedy zależeć od projektu lintera za pomocą konfiguracji lintChecks:

    Dynamiczny

            dependencies {
                // This tells the Gradle plugin to build ':lint-checks' into a lint.jar file
                // and package it with your module. If the module is an Android library,
                // other projects that depend on it automatically use the lint checks.
                // If the module is an app, lint includes these rules when analyzing the app.
                lintChecks project(':lint-checks')
            }
            

    Kotlin

            dependencies {
                // This tells the Gradle plugin to build ':lint-checks' into a lint.jar file
                // and package it with your module. If the module is an Android library,
                // other projects that depend on it automatically use the lint checks.
                // If the module is an app, lint includes these rules when analyzing the app.
                lintChecks(project(":lint-checks"))
            }
            

Zmiany w zachowaniu

  • Wtyczka Androida w wersji 3.0.0 usuwa niektóre interfejsy API, a jeśli ich używasz, kompilacja zostanie przerwana. Nie możesz już na przykład używać interfejsu Variants API do uzyskiwania dostępu do outputFile() obiektów ani używać processManifest.manifestOutputFile() do pobierania pliku manifestu dla każdego wariantu. Więcej informacji znajdziesz w artykule Zmiany w interfejsie API.
  • Nie musisz już określać wersji narzędzi do kompilacji (możesz więc usunąć właściwość android.buildToolsVersion). Domyślnie wtyczka automatycznie używa minimalnej wymaganej wersji narzędzi do kompilacji dla używanej wersji wtyczki Androida.
  • Możesz teraz włączać i wyłączać kompresję PNG w bloku buildTypes, jak pokazano poniżej. Kompresja PNG jest domyślnie włączona we wszystkich kompilacjach z wyjątkiem kompilacji debugowania, ponieważ wydłuża czas kompilacji projektów, które zawierają wiele plików PNG. Aby skrócić czas kompilacji innych typów kompilacji, wyłącz kompresję PNG lub przekonwertuj obrazy do formatu WebP.

    Dynamiczny

          android {
            buildTypes {
              release {
                // Disables PNG crunching for the release build type.
                crunchPngs false
              }
            }
          }
          

    Kotlin

          android {
            buildTypes {
              release {
                // Disables PNG crunching for the release build type.
                isCrunchPngs = false
              }
            }
          }
          
  • Wtyczka Androida automatycznie kompiluje teraz docelowe pliki wykonywalne skonfigurowane w zewnętrznych projektach CMake.
  • Musisz teraz dodać procesory adnotacji do ścieżki klasy procesora za pomocą annotationProcessor konfiguracji zależności.
  • Używanie przestarzałego polecenia ndkCompile jest teraz bardziej ograniczone. Zamiast tego przeprowadź migrację do CMake lub ndk-build, aby skompilować kod natywny, który chcesz spakować do pliku APK. Więcej informacji znajdziesz w artykule Migracja z ndkcompile.