Aktualizacje interfejsu API wtyczki Androida do obsługi Gradle

Ta strona śledzi wycofanie i usunięcie interfejsów API przez wtyczkę Androida Gradle (AGP), a także informacje o tym, jak odpowiednio zaktualizować kod.

Śledzenie wycofywania i usuwania interfejsów API

W tabeli poniżej znajdziesz informacje o wycofaniu i usunięciu interfejsów API AGP.

Interfejs API Wycofane w wersji AGP Usunięto z wersji AGP
Component.setAsmFramesComputationMode 7.2
Component.transformClassesWith 7.2
RenderScript 7.2
Przekształć 7.2 z Androidem 8.0

8.0 AGP

Poniżej znajdziesz ważne aktualizacje interfejsu API w wersji 8.0.

Interfejs Transform API został usunięty

Od wersji AGP 8.0 interfejs API Transform jest usuwany. Oznacza to, że wszystkie klasy w pakiecie com.android.build.api.transform zostaną usunięte.

Interfejs Transform API jest usuwany, aby zwiększyć wydajność kompilacji. Projekty, w których interfejs Transform API wymusza stosowanie AGP w celu korzystania z mniej zoptymalizowanego przepływu kompilacji, co może prowadzić do dużych regresji w czasie kompilacji. Trudno też korzystać z interfejsu Transform API i łączyć go z innymi funkcjami Gradle. Nowe interfejsy API mają ułatwić rozszerzenie AGP bez wprowadzania problemów z wydajnością i poprawnością.

Zapasowe interfejsy API

Transform API nie zastępuje jednego – dla każdego zastosowania dostępne są nowe, docelowe interfejsy API. Wszystkie zastępcze interfejsy API znajdują się w bloku androidComponents {}. Wszystkie te interfejsy API są dostępne od wersji 7.2 AGP.

Obsługa przekształcania kodu bajtowego

Do przekształcenia kodu bajtowego użyj interfejsu Instrumentation API. W przypadku bibliotek możesz zarejestrować instrumentację tylko dla lokalnych klas projektów. W przypadku aplikacji i testów możesz zarejestrować instrumentację tylko dla klas lokalnych lub wszystkich klas, w tym zależności lokalnych i zdalnych. Aby używać tego interfejsu API, instrument działa niezależnie w każdej klasie z ograniczonym dostępem do innych klas w ścieżce klasy (więcej informacji znajdziesz w sekcji createClassVisitor()). To ograniczenie poprawia wydajność zarówno pełnych, jak i przyrostowych kompilacji, a jednocześnie zapewnia prosty interfejs API. Obsługa każdej biblioteki odbywa się równolegle, gdy tylko jest gotowa, a nie po zakończeniu kompilacji. Ponadto zmiana w pojedynczej klasie oznacza, że tylko dotknięte nią klasy trzeba przystosować za pomocą kompilacji przyrostowej. Jeśli chcesz dowiedzieć się, jak korzystać z interfejsu Instrumentation API, zapoznaj się z przepisem na temat przekształcania klas za pomocą ASM.

Obsługa dodawania wygenerowanych zajęć do aplikacji

Aby dodać do aplikacji dodatkowe wygenerowane klasy, użyj interfejsu Artifacts API w MultipleArtifact.ALL_CLASSES_DIRS. Przede wszystkim użyj

artifacts.use(TaskProvider)
  .wiredWith(...)
  .toAppend(Artifact.Multiple)

za pomocą MultipleArtifact.ALL_CLASSES_DIRS, by dołączyć dodatkowe wygenerowane katalogi do klas projektu. Artifacts API automatycznie wybierze unikalną lokalizację, w której dane zadanie niestandardowe ma znaleźć dane wyjściowe. Przykład wykorzystania tego interfejsu API znajdziesz w przepisie addToAllClasses.

Obsługa przekształceń na podstawie analizy całego programu

Aby wdrożyć przekształcenia oparte na analizie programu, wszystkie klasy można przekształcić razem w ramach jednego zadania. Tego podejścia należy używać ostrożnie, ponieważ ma ono znacznie wyższy koszt wydajności niż przy użyciu interfejsu Instrumentation API. Jeśli Twoja wtyczka używa tego interfejsu API, zalecamy włączenie jej dla każdego typu kompilacji, tak aby deweloper aplikacji mógł ją wyłączyć na potrzeby kompilacji.

Aby zarejestrować zadanie, które razem przekształca wszystkie klasy, wtyczka Androida do obsługi Gradle w wersji 7.4 wprowadza interfejs API Artifacts.forScope. Aby przekształcić wszystkie klasy w bieżącym projekcie, użyj funkcji Artifacts.forScope.PROJECT. Aby przekształcić wszystkie klasy w bieżącym projekcie, zaimportowane projekty i wszystkie zależności zewnętrzne, użyj funkcji Artifacts.forScope.ALL. Poniższy kod pokazuje, jak za pomocą Artifacts.forScope.ALL zarejestrować zadanie, które przekształca wszystkie klasy razem:

variant.artifacts.forScope(ScopedArtifacts.Scope.ALL)
    .use(taskProvider)
    .toTransform(
        ScopedArtifact.CLASSES,
        ModifyClassesTask::allJars,
        ModifyClassesTask::allDirectories,
        ModifyClassesTask::output,
    )

Przykład wykorzystania tego interfejsu API znajdziesz w przepisie modyfikatoraProjectClasses, natomiast w przepisie customizeAgpDsl Recipe znajdziesz przykład rejestrowania niestandardowych rozszerzeń do typów kompilacji Androida.

Jeśli w Twoim przypadku nie występuje żaden z interfejsów API AndroidKomponent, zgłoś błąd.

Kilka powszechnie używanych wtyczek zostało już przeniesionych do nowych interfejsów API, w tym wtyczka monitorowania wydajności Firebase (1.4.1 jest zgodna z AGP 8.0) oraz wtyczka Hilt Gradle (2.40.1 jest zgodna z AGP 8.0). Asystent uaktualnienia AGP pomoże też programistom projektów w aktualizowaniu często używanych wtyczek w razie potrzeby.

Jeśli używasz interfejsu Transform API za pomocą wtyczki innej firmy, poinformuj autora o tym, że jego wtyczka wymaga aktualizacji, by działała z nowymi interfejsami API w AGP 8.0.

7.2 AGP

Poniżej znajdziesz ważne aktualizacje interfejsów API w AGP 7.2.

Interfejs RenderScript został wycofany

Od wersji AGP 7.2 interfejsy API RenderScript zostały wycofane. Będą one nadal działać, ale będą wywoływać ostrzeżenia i zostaną całkowicie usunięte w przyszłych wersjach AGP. Wskazówki dotyczące rezygnacji z renderowania znajdziesz w sekcji Migracja z RenderScriptu.

Metody Component.transformClassesWith i Component.setAsmFramesComputationMode zostały wycofane

Od AGP 7.2 interfejsy API instrumentacji klas kodu bajtowego Component.transformClassesWith i Component.setAsmFramesComputationMode zostały wycofane. Zostały przeniesione do nowego bloku (Component.instrumentation), który zawiera wszystkie interfejsy API związane z konfigurowaniem procesu instrumentacji. Aby nadal korzystać z tych funkcji instrumentacji, użyj odpowiednich interfejsów API w nowym bloku, jak pokazano w tym fragmencie kodu:

androidComponents {
      onVariants(selector().all(), {
          instrumentation.transformClassesWith(AsmClassVisitorFactoryImpl.class,
                                               InstrumentationScope.Project) { params ->
              params.x = "value"
          }
          instrumentation.setAsmFramesComputationMode(
              COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS
          )
      })
  }