Android Gradle Plugin 3.5 came out in August 2019 as a part of Project Marble that focuses on making Android Studio and build tools more stable and polished. Thus, the only notable update is Data Binding now supports incremental annotation processing.
Having Data Binding annotation processor support incremental processing is just a small part of much bigger puzzle. Let's have a look on how annotation processing on Android evolves and what configuration do we need to run it incrementally.
The source-level annotation processing first appeared in Java 5 long before we heard about Android.
Annotation processing in context of Android development appeared around 2013 with libraries like Dagger or Butter Knife that helps to reduce writing boilerplate code i.e. for Android system bindings.
But, as Android projects grew, the build times become longer. And there appeared the need for incremental annotation processing that promises to lower the build times.
The first step for incremental annotation processing is to have a support during build orchestration in build system - Gradle in our case. It took a couple years to make it, but finally in April 2018 Gradle 4.7 came out. Unfortunately, the incremental annotation processing is challenging and it was not possible to have for all the annotation processors incremental out of the box.
Gradle 4.7 came with a new annotation processing API that allows annotation processors to work incrementally. In Gradle 5.0 the incremental annotation processing was optimized for performance.
Anyway, the Gradle annotation processing API has one big limitation: to run an annotation processor incrementally, all of the build annotation processors must be incremental. If only one of them does not adopt the new Gradle API, no one can run incrementally.
So now it is annotation processor author's turn to adopt it and Gradle team is very supportive in this. Soon there was a list of major annotation processing libraries in Gradle docs describing their state on journey to incremental.
Today, two years later, there is still quite a lot of work to be done for some libraries.
When Kotlin 1.0 has been released in 2016 it had an extra ordinary interoperability with Java. With one exception, annotation processing. Java annotation processing, baked to
javac compiler, does not work with Kotlin source code at all, so there was a need for completely new tool:
kapt (Kotlin Annotation Processing Tool).
kapt implementation was quite cumbersome to use as there was no way for Kotlin source code classes to refer to any code generated by the annotation processor.
The second version of
kapt overcome this problem by generating stubs of Kotlin classes, but there were still issues with injecting values into fields etc.
So there came the complete re-write known as
kapt3 and everything was good. Until Gradle 4.7 appeared with incremental annotation processing, that works for Java but not for Kotlin and we had another challenge for
It took another year. In April 2019 Kotlin 1.3.30 has been released with
kapt supporting incremental annotation processors in an experimental mode. Later that year Kotlin 1.3.50 came out with stable implementation of incremental annotation processing support enabled by default.
Let's sum it up. If you want your annotation processors to run incrementally, you need to do three steps:
- Make sure you are using Gradle 5.0 or newer.
- Check that all of your annotation processors are configured to run incrementally. Some do this by default, some need to be configured (overview in Gradle docs might help).
- If you have Kotlin code, make sure that you are using Kotlin 1.3.50 or newer.
Happy incremental annotation processing!