Cómo agregar procesadores de anotaciones

En esta página, se incluye una guía detallada sobre cómo agregar y configurar procesadores de anotaciones como dependencias del proyecto. Para obtener más información sobre los procesadores de anotaciones, consulta la entrada en Cómo configurar dependencias.

Si agregas procesadores de anotaciones a la ruta de clase de tu compilación, verás un mensaje de error similar al siguiente:

Error: Annotation processors must be explicitly declared now.

Para corregir este error, agrega procesadores de anotaciones a tu proyecto mediante la configuración de tu dependencia con annotationProcessor, como se muestra a continuación:

Kotlin

dependencies {
    // Adds libraries defining annotations to only the compile classpath.
    compileOnly("com.google.dagger:dagger:version-number")
    // Adds the annotation processor dependency to the annotation processor classpath.
    annotationProcessor("com.google.dagger:dagger-compiler:version-number")
}

Groovy

dependencies {
    // Adds libraries defining annotations to only the compile classpath.
    compileOnly 'com.google.dagger:dagger:version-number'
    // Adds the annotation processor dependency to the annotation processor classpath.
    annotationProcessor 'com.google.dagger:dagger-compiler:version-number'
}

Nota: El complemento de Android para Gradle 3.0.0+ ya no admite el complemento android-apt.

Cómo pasar argumentos a procesadores de anotaciones

Si necesitas pasar argumentos a un procesador de anotaciones, puedes hacerlo mediante el bloque AnnotationProcessorOptions en la configuración de compilación de tu módulo. Por ejemplo, si quieres transmitir tipos de datos primitivos como pares clave-valor, puedes utilizar la propiedad argument, como se muestra a continuación:

Kotlin

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments += mapOf("key1" to "value1",
                                   "key2" to "value2")
            }
        }
    }
}

Groovy

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                argument 'key1', 'value1'
                argument 'key2', 'value2'
            }
        }
    }
}

Sin embargo, cuando uses el complemento de Android para Gradle 3.2.0 o versiones posteriores, necesitarás pasar argumentos de procesadores que representen archivos o directorios por medio de la interfaz CommandLineArgumentProvider de Gradle.

Usar CommandLineArgumentProvider te permite a ti o al autor del procesador de anotaciones mejorar la precisión y el rendimiento de las compilaciones limpias incrementales y almacenadas en caché aplicando anotaciones del tipo de propiedad de compilación incremental a cada argumento.

Por ejemplo, la clase que se muestra a continuación implementa CommandLineArgumentProvider y anota cada argumento para el procesador.

Kotlin

class MyArgsProvider(
    // Annotates each directory as either an input or output for the
    // annotation processor.
    @get:InputFiles
    // Using this annotation helps Gradle determine which part of the file path
    // should be considered during up-to-date checks.
    @get:PathSensitive(PathSensitivity.RELATIVE)
    val inputDir: FileCollection,

    @get:OutputDirectory
    val outputDir: File
) : CommandLineArgumentProvider {
    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the
    // annotation processor.

    override fun asArguments(): Iterable<String> {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        return listOf("-AinputDir=${inputDir.singleFile.absolutePath}",
                      "-AoutputDir=${outputDir.absolutePath}")
    }
}

android {...}

Groovy

class MyArgsProvider implements CommandLineArgumentProvider {

    // Annotates each directory as either an input or output for the
    // annotation processor.
    @InputFiles
    // Using this annotation helps Gradle determine which part of the file path
    // should be considered during up-to-date checks.
    @PathSensitive(PathSensitivity.RELATIVE)
    FileCollection inputDir

    @OutputDirectory
    File outputDir

    // The class constructor sets the paths for the input and output directories.
    MyArgsProvider(FileCollection input, File output) {
        inputDir = input
        outputDir = output
    }

    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the
    // annotation processor.
    @Override
    Iterable<String> asArguments() {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        ["-AinputDir=${inputDir.singleFile.absolutePath}",
         "-AoutputDir=${outputDir.absolutePath}"]
    }
}

android {...}

Después de definir una clase que implemente CommandLineArgumentProvider, debes crear una instancia y pasarla al complemento de Android con el método annotationProcessorOptions.compilerArgumentProvider, como se muestra a continuación.

Kotlin

// This is in your module's build.gradle file.
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                // Creates a new MyArgsProvider object, specifies the input and
                // output paths for the constructor, and passes the object
                // to the Android plugin.
                compilerArgumentProvider(MyArgsProvider(files("input/path"),
                                                          file("output/path")))
            }
        }
    }
}

Groovy

// This is in your module's build.gradle file.
android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                // Creates a new MyArgsProvider object, specifies the input and
                // output paths for the constructor, and passes the object
                // to the Android plugin.
                compilerArgumentProvider new MyArgsProvider(files("input/path"),
                                         new File("output/path"))
            }
        }
    }
}

Para descubrir cómo la implementación de CommandLineArgumentProvider ayuda a mejorar el rendimiento de la compilación, lee Cómo almacenar proyectos de Java en caché.

Cómo inhabilitar la comprobación de errores del procesador de anotaciones

Si tienes dependencias en la ruta de clase de compilación que incluyen procesadores de anotaciones que no necesitas, puedes inhabilitar la comprobación de errores si agregas lo siguiente a tu archivo build.gradle.kts. Ten en cuenta que los procesadores de anotaciones que agregues a la ruta de clase de la compilación aún no se agregarán a la ruta de clase del procesador.

Kotlin

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                argument("includeCompileClasspath", "false")
            }
        }
    }
}

Groovy

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath false
            }
        }
    }
}

Si usas Kotlin y kapt:

Kotlin

android {
    ...
    defaultConfig {
        ...
        kapt {
            includeCompileClasspath = false
        }
    }
}

Groovy

android {
    ...
    defaultConfig {
        ...
        kapt {
            includeCompileClasspath false
        }
    }
}

Si experimentas problemas luego de migrar los procesadores de anotaciones de tu proyecto a la ruta de clase del procesador, puedes habilitar los procesadores de anotaciones en la ruta de clase de la compilación mediante la configuración de includeCompileClasspath en true. Sin embargo, no se recomienda configurar esta propiedad en true y la opción para hacerlo se quitará en una actualización futura del complemento de Android.