Actualizaciones de las API del complemento de Android para Gradle

En esta página, se realiza un seguimiento de las bajas y las eliminaciones de las API del complemento de Android para Gradle (AGP), y se brinda información a fin de actualizar el código según corresponda.

Seguimiento de eliminaciones y bajas de las API

En la siguiente tabla, se resume cuándo las API de AGP están obsoletas y se quitan, en términos de la versión de AGP.

API Obsoleta en la versión de AGP Se quitó de la versión de AGP
Component.setAsmFramesComputationMode 7.2
Component.transformClassesWith 7.2
RenderScript 7.2
Transform 7.2 8.0

AGP 8.0

Las siguientes son actualizaciones importantes de las API para AGP 8.0.

Se quitó la API de Transform

A partir de AGP 8.0, se quita la API de Transform. Esto significa que se quitan todas las clases del paquete com.android.build.api.transform.

Se está quitando la API de Transform para mejorar el rendimiento de la compilación. Los proyectos que usan la API de Transform fuerzan a AGP a usar un flujo menos optimizado para la compilación que pueda generar grandes regresiones en los tiempos de compilación. También es difícil usar la API de Transform y combinarla con otras funciones de Gradle. El objetivo de las API de reemplazo es facilitar la extensión de AGP sin introducir problemas de rendimiento ni de corrección de la compilación.

API de reemplazo

No hay un solo reemplazo para la API de Transform; hay API nuevas y orientadas a cada caso de uso. Todas las API de reemplazo están en el bloque androidComponents {}. Todas estas API están disponibles de AGP 7.2 en adelante.

Compatibilidad para transformar el código de bytes

Para transformar el código de bytes, usa la API de Instrumentation. En el caso de las bibliotecas, puedes registrar una instrumentación solo para las clases de proyectos locales. En el caso de las apps y las pruebas, puedes registrar una instrumentación solo para las clases locales o todas las clases, incluidas las dependencias locales y remotas. Para usar esta API, la instrumentación se ejecuta de forma independiente en cada clase, con acceso limitado a otras clases en la ruta de clase (consulta createClassVisitor() para obtener más información). Esta restricción mejora el rendimiento de las compilaciones incrementales y completas, y mantiene la superficie de la API simple. Cada biblioteca se instrumenta en paralelo en cuanto está lista, en lugar de después de que se complete toda la compilación. Además, un cambio en una sola clase implica que solo se deben reinstrumentar las clases afectadas en una compilación incremental. Para ver un ejemplo de cómo usar la API de Instrumentation, consulta la receta de AGP Cómo transformar clases con ASM.

Compatibilidad para agregar clases generadas a tu app

Para agregar más clases generadas a la app, usa la API de Artifacts con MultipleArtifact.ALL_CLASSES_DIRS. Usa específicamente

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

con MultipleArtifact.ALL_CLASSES_DIRS para agregar directorios generados adicionales a las clases de proyecto. La API de Artifacts seleccionará automáticamente una ubicación única para la salida de tu tarea personalizada. Consulta la receta de addToAllClasses para ver un ejemplo de cómo usar esta API.

Compatibilidad con transformaciones basadas en análisis del programa completo

Para implementar transformaciones basadas en el análisis del programa completo, todas las clases pueden transformarse en una sola tarea. Este enfoque debe usarse con precaución, ya que tiene un costo de rendimiento de compilación mucho más alto que usar la API de Instrumentation. Si tu complemento usa esta API, se recomienda que la transformación se habilite por tipo de compilación, de modo que el desarrollador de apps pueda inhabilitarla para las compilaciones de desarrollo. En el siguiente código, se muestra cómo registrar una tarea que transforma todas las clases juntas.

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

Usa esto con MultipleArtifact.ALL_CLASSES_DIRS y MultipleArtifact.ALL_CLASSES_JARS para conectar todas las entradas y salidas necesarias a tu tarea personalizada. Consulta la receta de modificadorAllClasses para ver un ejemplo de cómo usar esta API y la receta de customAgpDsl para ver un ejemplo de cómo registrar extensiones personalizadas para los tipos de compilación de Android.

Si ninguna de las API de AndroidComponents cubre tu caso de uso, informa un error.

Ya se migraron varios complementos que se usan con frecuencia para usar estas API nuevas, incluido el complemento de supervisión del rendimiento de Firebase (1.4.1 es compatible con AGP 8.0) y el complemento de Hilt para Gradle (2.40.1 es compatible con AGP 8.0). El Asistente de actualización de AGP también ayudará a los desarrolladores de proyectos a actualizar los complementos que se usan con frecuencia según sea necesario.

Si usas la API de Transform a través de un complemento de terceros, informa al autor que su complemento deberá actualizarse para funcionar con las nuevas API de AGP 8.0.

AGP 7.2

Las siguientes son actualizaciones importantes de las API para AGP 7.2.

RenderScript dejó de estar disponible

A partir de AGP 7.2, las API de RenderScript dejaron de estar disponibles. Seguirán funcionando, pero invocarán advertencias y se quitarán por completo en versiones futuras de AGP. Si deseas obtener orientación para realizar la transición de RenderScript, consulta Cómo migrar desde RenderScript.

Component.transformClassesWith y Component.setAsmFramesComputationMode dejaron de estar disponibles

A partir de AGP 7.2, las API de instrumentación de código de bytes de clase Component.transformClassesWith y Component.setAsmFramesComputationMode dejaron de estar disponibles. Se movieron a un nuevo bloque, Component.instrumentation, que contiene todas las API relacionadas con la configuración del proceso de instrumentación. Para continuar usando estas funciones de instrumentación, usa las API correspondientes en el bloque nuevo, como se muestra en el siguiente fragmento de código:

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