Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Cómo usar las funciones y las API del lenguaje Java 8

El complemento de Gradle para Android 3.0.0 y versiones posteriores admiten todas las funciones del lenguaje Java 7 y un subconjunto de las de Java 8 que varían según la versión de la plataforma. Cuando compilas tu app con el complemento de Gradle para Android 4.0.0 y versiones posteriores, puedes usar varias API de lenguaje Java 8 sin requerir un nivel de API mínimo para la app.

En esta página, se describen las funciones del lenguaje Java 8 que puedes utilizar, la manera de configurar correctamente tu proyecto para usarlas y los problemas conocidos que puedes experimentar. Además, mira el siguiente video para obtener una descripción general.

Nota: Cuando se desarrollan apps para Android, el uso de funciones del lenguaje Java 8 es opcional. Puedes mantener los valores de compatibilidad de origen y destino de tu proyecto en Java 7, pero debes utilizar JDK 8 para la compilación.

El complemento de Gradle para Android proporciona compatibilidad integrada para el uso de ciertas funciones del lenguaje Java 8 y bibliotecas de terceros que las usan. Como se muestra en la Figura 1, la cadena de herramientas predeterminada implementa las funciones nuevas del lenguaje realizando transformaciones de código de bytes, con el nombre desugar, como parte de la compilación con D8 o R8 de archivos de clases en código DEX.

Figura 1: Compatibilidad con funciones del lenguaje Java 8 mediante transformaciones de código de bytes desugar

Compatibilidad con funciones del lenguaje Java 8 (complemento de Gradle para Android 3.0.0 y versiones posteriores)

A fin de comenzar a usar las funciones del lenguaje Java 8 compatibles, actualiza el complemento para Android a 3.0.0 (o versiones posteriores). Luego, para cada módulo que utilice funciones del lenguaje Java 8 (ya sea en su código fuente o a través de dependencias), actualiza el archivo build.gradle del módulo, como se muestra a continuación:

android {
  ...
  // Configure only for each module that uses Java 8
  // language features (either in its source code or
  // through dependencies).
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
  // For Kotlin projects
  kotlinOptions {
    jvmTarget = "1.8"
  }
}

Cuando compilas tu app con el complemento de Gradle para Android 3.0.0 y versiones posteriores, el complemento no es compatible con todas las funciones del lenguaje Java 8. Las siguientes funciones del lenguaje ahora están disponibles en cualquier nivel de API:

Función del lenguaje Java 8 Notas
Expresiones lambda Ten en cuenta que Android no admite la serialización de expresiones lambda.
Referencias de métodos  
Anotaciones de tipos La información de anotación de tipos solo está disponible durante el tiempo de compilación y no en el de ejecución. Además, la plataforma admite TYPE en el nivel de API 24 y versiones anteriores, pero no ElementType.TYPE_USE o ElementType.TYPE_PARAMETER.
Métodos de interfaz predeterminados y estáticos  
Repetición de anotaciones  

Además de las funciones del lenguaje Java 8 anteriores, las versiones de complementos 3.0.0 y posteriores extienden la compatibilidad con try-with-resources para todos los niveles de API de Android.

Por el momento, Desugar no admite MethodHandle.invoke ni MethodHandle.invokeExact. Si tu código fuente o una de las dependencias del módulo usan uno de estos métodos, debes especificar minSdkVersion 26 o una versión posterior. De lo contrario, verás el siguiente error:

Dex: Error converting bytecode to dex:
Cause: signature-polymorphic method called without --min-sdk-version >= 26

En algunos casos, es posible que tu módulo no use los métodos invoke ni invokeExact, incluso si forman parte de una dependencia de biblioteca. Por lo tanto, para seguir usando esa biblioteca con minSdkVersion 25 o versiones anteriores, habilita la reducción de código a fin de quitar los métodos sin utilizar. Si eso no funciona, procura usar una biblioteca alternativa que no emplee los métodos no admitidos.

Las funciones de expansión de sintaxis de Java 8 y versiones posteriores que están disponibles en el complemento de Gradle para Android 3.0.0 no permiten que las clases y API adicionales (como java.util.stream.*) estén disponibles para su uso en versiones anteriores de Android. La compatibilidad con la expansión de sintaxis parcial de la API de Java está disponible en el complemento de Gradle para Android 4.0.0 o versiones posteriores, y se describe en la siguiente sección.

Compatibilidad con la expansión de sintaxis de API en Java 8 y versiones posteriores (complemento de Gradle para Android 4.0.0 y versiones posteriores)

Si compilas tu app con el complemento de Gradle para Android 4.0.0 o una versión posterior, el complemento extiende la compatibilidad a fin de usar varias API del lenguaje Java 8 sin requerir un nivel de API mínimo para la app.

Esa compatibilidad adicional para versiones anteriores de la plataforma es posible porque el complemento 4.0.0 y versiones posteriores amplían el motor de expansión de sintaxis a fin de poder usar desugar en las API del lenguaje Java. Por lo tanto, puedes incluir API de lenguaje estándar que solo estaban disponibles en las versiones recientes de Android (como java.util.streams) en apps que admiten versiones anteriores de Android.

El siguiente conjunto de API es compatible cuando se compila tu app con el complemento de Gradle para Android 4.0.0 o una versión posterior:

  • Flujos secuenciales (java.util.stream)
  • Un subconjunto de java.time
  • java.util.function
  • Adiciones recientes a java.util.{Map,Collection,Comparator}
  • Opcionales (java.util.Optional, java.util.OptionalInt y java.util.OptionalDouble) y algunas otras clases nuevas que son útiles para las API anteriores
  • Algunas adiciones a java.util.concurrent.atomic (métodos nuevos en AtomicInteger, AtomicLong y AtomicReference)
  • ConcurrentHashMap (con correcciones de errores para Android 5.0)

Para obtener una lista completa de las API compatibles, visita la página sobre API de Java 8 y versiones posteriores disponibles mediante expansión de sintaxis.

Para admitir esas API de lenguaje, el complemento compila un archivo DEX separado que contiene una implementación de las API faltantes y lo incluye en tu app. El proceso de expansión de sintaxis reescribe el código de tu app a fin de usar esa biblioteca en el tiempo de ejecución.

Para habilitar la compatibilidad con esas API de lenguaje en cualquier versión de la plataforma de Android, actualiza el complemento para Android a4.0.0 (o versiones posteriores) e incluye lo siguiente en el archivo build.gradle del módulo:

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.9'
}