Complemento de Android para Gradle 3.0.0 (octubre de 2017)

El complemento de Android para Gradle 3.0.0 incluye una variedad de cambios que están destinados a solucionar problemas de rendimiento de proyectos grandes.

Por ejemplo, en un proyecto preliminar de muestra con aproximadamente 130 módulos y una gran cantidad de dependencias externas (pero sin código ni recursos), puedes experimentar mejoras de rendimiento similares a las siguientes:

Versión del complemento de Android y Versión de Gradle Complemento de Android 2.2.0 y Gradle 2.14.1 Complemento de Android 2.3.0 y Gradle 3.3 Complemento de Android 3.0.0 y Gradle 4.1
Configuración (p. ej., ejecución de ./gradlew --help) Aprox. 2 min Aprox. 9 s Aprox. 2.5 s
Cambio en Java de 1 línea (cambio de implementación) Aprox. 2 min y 15 s Aprox. 29 s Aprox. 6.4 s

Algunos de estos cambios dividen las compilaciones existentes. Por lo tanto, debes considerar el esfuerzo de migrar el proyecto antes de usar el nuevo complemento.

Si no experimentas las mejoras de rendimiento que se describen anteriormente, informa un error e incluye un seguimiento de la compilación con el Generador de perfiles de Gradle.

Esta versión del complemento para Android requiere lo siguiente:

  • Gradle 4.1 o una versión posterior (si deseas obtener más información, consulta la sección que abarca cómo actualizar Gradle)
  • Herramientas de compilación 26.0.2 o una versión posterior (con esta actualización, ya no es necesario especificar una versión para las herramientas de compilación, ya que el complemento usa la versión mínima requerida de forma predeterminada, por lo que puedes quitar la propiedad android.buildToolsVersion)

3.0.1 (noviembre de 2017)

Esta es una actualización menor que brinda compatibilidad con Android Studio 3.0.1 e incluye correcciones de errores y mejoras de rendimiento.

Optimizaciones

  • Se mejoró el paralelismo en proyectos que tienen varios módulos mediante un gráfico de tareas refinado.
  • Cuando se realizan cambios en la dependencia, Gradle realiza compilaciones más rápidas al no volver a compilar los módulos que no tienen acceso a la API de esa dependencia. Debes restringir las dependencias que filtran sus APIs a otros módulos usando las nuevas configuraciones de dependencias de Gradle: implementation, api, compileOnly y runtimeOnly.
  • La velocidad de compilación incremental es mayor debido a la conversión a DEX por clase. Ahora cada clase se compila en archivos DEX independientes, y solo las clases que se modifican se vuelven a convertir a DEX. También se mejoraron las velocidades de compilación para apps que establecen minSdkVersion en 20 o un valor inferior, y usan multi-dex heredado.
  • Se mejoraron las velocidades de compilación mediante la optimización de determinadas tareas para usar resultados en caché. Si quieres aprovechar esta optimización, primero debes habilitar la caché de compilación de Gradle.
  • Se mejoró el procesamiento incremental de recursos gracias al uso de AAPT2, que ahora está habilitada de forma predeterminada. Si tienes problemas a la hora de usar AAPT2, informa el error. También puedes inhabilitar AAPT2 si configuras android.enableAapt2=false en tu archivo gradle.properties y reinicias el daemon de Gradle mediante la ejecución de ./gradlew --stop desde la línea de comandos.

Funciones nuevas

  • Se incluyó la administración de dependencias con detección de variantes. Cuando se compila la variante de un módulo, el complemento hace coincidir automáticamente las variantes de dependencias de módulos de biblioteca locales con la del módulo que estás compilando.
  • Se incluyó un complemento de módulo de funciones nuevo compatible con Apps instantáneas Android y su SDK, que puedes descargar con SDK Manager. Si deseas obtener más información para crear módulos de funciones con el complemento nuevo, consulta Estructura de una app instantánea con varias funciones.
  • Se agregó compatibilidad integrada para usar determinadas funciones de lenguaje y bibliotecas Java 8. Jack se dio de baja y ya no se necesita, y deberás inhabilitarlo antes de usar la compatibilidad mejorada con Java 8 que está integrada en la cadena de herramientas predeterminada. Si deseas obtener más información, consulta Cómo usar funciones del lenguaje Java 8.
  • Se agregó compatibilidad para ejecutar pruebas con Android Test Orchestrator, que permite ejecutar cada una de las pruebas de la app dentro de la invocación de Instrumentation. Dado que cada prueba se ejecuta en su propia instancia de Instrumentation, los estados compartidos entre las pruebas no se acumulan en la CPU ni en la memoria del dispositivo. Además, aunque falle una de las pruebas, solo se eliminará su propia instancia de Instrumentation, de modo que aún se seguirá ejecutando el resto de las pruebas.

    • Se agregó testOptions.execution para determinar si se usará la organización de la prueba en el dispositivo. Si deseas usar Android Test Orchestrator, debes especificar ANDROID_TEST_ORCHESTRATOR, como se muestra a continuación. De forma predeterminada, esta propiedad se establece en HOST, que inhabilita la organización en el dispositivo y es el método estándar para ejecutar pruebas.

    Groovy

            android {
              testOptions {
                execution 'ANDROID_TEST_ORCHESTRATOR'
              }
            }
            

    Kotlin

            android {
              testOptions {
                execution = "ANDROID_TEST_ORCHESTRATOR"
              }
            }
            
  • Se agregó una nueva configuración de dependencias androidTestUtil, que permite instalar otro APK auxiliar de prueba antes de ejecutar las pruebas de instrumentación, como Android Test Orchestrator:

    Groovy

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

    Kotlin

            dependencies {
              androidTestUtil("com.android.support.test:orchestrator:1.0.0")
              ...
            }
            
  • Se agregó testOptions.unitTests.includeAndroidResources, que brinda compatibilidad con pruebas de unidades que requieren recursos de Android, como Roboelectric. Cuando se establece esta propiedad en true, el complemento lleva a cabo la combinación de recursos, elementos y manifiestos antes de ejecutar las pruebas de unidades. Luego, las pruebas pueden inspeccionar com/android/tools/test_config.properties en la ruta de clase para las siguientes claves:

    • android_merged_assets: Es la ruta de acceso absoluta del directorio de recursos combinados.

      Nota: Para los módulos de biblioteca, los recursos combinados no contienen los elementos de las dependencias (consulta el error #65550419).

    • android_merged_manifest: Es la ruta de acceso absoluta al archivo de manifiesto combinado.

    • android_merged_resources: Es la ruta de acceso absoluta al directorio de recursos combinados, que contiene todos los recursos del módulo y todas sus dependencias.

    • android_custom_package: Es el nombre del paquete de la clase R final. Si modificas de manera dinámica el ID de aplicación, es posible que el nombre de este paquete no coincida con el atributo package en el manifiesto de la app.

  • Compatibilidad con fuentes como recursos (una función nueva que se introdujo en Android 8.0 (nivel de API 26)).
  • Se agregó compatibilidad para APK específicos de idioma con el SDK de Apps instantáneas Android 1.1 y versiones posteriores.
  • Ahora es posible cambiar el directorio de salida del proyecto de compilación nativo externo, como se muestra a continuación:

    Groovy

            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"
                    }
                }
            }
            
  • Ahora puedes usar CMake 3.7 o versiones posteriores cuando compiles proyectos nativos desde Android Studio.
  • La nueva configuración de dependencias lintChecks permite compilar un JAR que define reglas de lint personalizadas y empaquetarlo en tus proyectos de AAR y APK.

    Las reglas de lint personalizadas deben pertenecer a un proyecto separado que genere un único JAR e incluya solo dependencias compileOnly. Luego, otros módulos de app y biblioteca pueden depender del proyecto de lint mediante la configuración lintChecks:

    Groovy

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

Cambios en el comportamiento

  • El complemento para Android 3.0.0 quita determinadas APIs que, si se usan, se dañará la compilación. Por ejemplo, ya no es posible usar la API de variantes para acceder a objetos outputFile() ni usar processManifest.manifestOutputFile() a fin de obtener el archivo de manifiesto de cada variante. Si deseas obtener más información, consulta Cambios en la API.
  • Ya no es necesario especificar una versión para las herramientas de compilación (por lo tanto, ahora puedes quitar la propiedad android.buildToolsVersion). De forma predeterminada, el complemento usa automáticamente la versión mínima requerida de las herramientas de compilación correspondiente a la versión del complemento para Android que estás usando.
  • Ahora puedes habilitar o inhabilitar la compresión de PNG en el bloque buildTypes, como se muestra a continuación. La compresión de PNG ahora está habilitada de forma predeterminada para todas las compilaciones, excepto para las de depuración, ya que aumentan el tiempo de compilación en proyectos que incluyen muchos archivos PNG. Por lo tanto, a fin de mejorar los tiempos de compilación en otros tipos de compilaciones, debes inhabilitar la compresión de PNG o convertir las imágenes a WebP.

    Groovy

          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
              }
            }
          }
          
  • El complemento para Android ahora compila automáticamente los objetivos ejecutables que se configuran en los proyectos de CMake externos.
  • Ahora debes agregar procesadores de anotaciones a la ruta de clase del procesador usando la configuración de dependencia annotationProcessor.
  • Ahora, el uso del elemento obsoleto ndkCompile tiene más restricciones. En su lugar, debes comenzar a utilizar CMake o ndk-build para compilar código nativo que quieras empaquetar en tu APK. Para obtener más información, consulta Cómo migrar desde ndkcompile.