How Does Booster Support AGP 8.0?
It has been over a month since AGP 8.0 was officially released, and Booster’s adaptation to AGP 8.0 is still underway. The main challenge is that AGP 8.0 removed many APIs that were previously only deprecated, including parts of the Transform API. The Legacy Variant API is also on its way out, replaced by the Instrumentation API, Artifacts API, and New Variant API. Although these new APIs have existed since AGP 7.0, they kept changing through AGP 7.4 and were never fully stable. They are also completely incompatible with the old APIs. We were not sure what the final stable form would look like. Given that Booster already supports 12 versions from AGP 3.3 to AGP 7.4, making drastic API changes would be a significant migration challenge for Booster users. Now that AGP 8.0 has finally removed the deprecated APIs, we believe its API surface has stabilized. Time to go big.
Why Did AGP Deprecate the Legacy API?
The short answer: for a smoother build experience. But why could the old APIs not deliver that, while the new ones can?
Redundant Transforms
This brings us to Gradle. AGP’s entire build system is based on Gradle. Back in 2015 when AGP 1.5 officially introduced the Transform API, Gradle was still at version 2.x – far weaker than today’s Gradle 8.x. It did not even have a proper Transform API; ArtifactTransform only arrived in 3.4. So AGP had to implement its own Transform API to handle bytecode processing during Android app builds. As AGP continued optimizing build performance, Gradle 5.3 finally introduced TransformAction in 2019, primarily to solve dependency transform issues and lay groundwork for Configuration Cache.
In AGP’s Transform Pipeline, project dependencies and the project’s own classes were not strictly separated – they were processed together. This created redundancy with Gradle’s own dependency transform mechanism. To maximize Android build optimization, the AGP team made deliberate tradeoffs, reusing Gradle’s transforms wherever possible to avoid redundant I/O. This is also why Booster consolidates the entire transform process, solving all class transformations in a single I/O pass.
Parallel Execution
Another issue is AGP’s own transform implementation. Both the legacy TransformTask and TransformClassesWithAsmTask process primarily in serial and cannot achieve full parallelism – leaving significant room for optimization.
Take TransformTask as an example. Each Transform creates a task, and AGP itself chains many Transform instances into a pipeline. Each one processes data, writes results to disk at some location, then passes the path to the next TransformTask, which writes to yet another location, and so on until all Transform tasks are complete. The more Transform instances there are, the more TransformTask instances are created, and I/O operations grow linearly.
Although AGP later introduced TransformClassesWithAsmTask, the implementation was just a for loop:
1 | private fun processJars( |
It was not until AGP 7.1 that JAR processing became parallel, using Gradle’s WorkerExecutor. This not only maximizes CPU utilization but also makes the most of Gradle’s caching mechanisms.
While AGP’s implementation was far from elegant, the improvement over the Legacy Transform API was substantial: consolidating many TransformTask instances into a single TransformClassesWithAsmTask drastically reduced I/O overhead.
Booster’s Approach
Artifacts API
The Artifacts API was introduced in AGP 4.1. At the time, AGP’s intent behind this API was not entirely clear to us, since it was not built from scratch but redesigned from the original VariantScope.getArtifacts(). The original Artifacts were scattered across internal APIs used only within AGP. Although the Artifacts API has existed since AGP 4.1, it kept changing and did not truly stabilize until AGP 7.2.
Similar to the old Transform API, the Artifacts API implementation also requires a Task to back it – see TransformClassesWithAsmTask for reference. Compared to the Transform API, it significantly reduces unnecessary I/O. However, if developers still implement custom transforms on top of this API, while writing the code is easier than directly manipulating tasks, the runtime behavior is fundamentally the same as the old Transform API – one task finishes and hands its results to the next, still unable to parallelize.
For Booster, if we can unify these custom transform tasks, we can drastically reduce unnecessary I/O operations:
Instrumentation API
Back in What Does the Deprecation of AGP Transform API Mean?, I mentioned Gradle’s native TransformAction API. The Instrumentation API that AGP introduced starting from 4.2 is essentially built on Gradle’s native TransformAction. As shown in the earlier diagram, TransformAction is primarily used for transforming dependency JARs/classes.
Unlike the TransformAction API, the Instrumentation API adds an abstraction layer similar to Booster’s Transformer, namely AsmClassVisitorFactory, which creates ASM ClassVisitor instances.
In theory, Booster could also solve the transform problem through the Instrumentation API. It would simply require having the Transformer implement the AsmClassVisitorFactory interface:
Trade-off
From a technical standpoint, both the Instrumentation API and the Artifacts API can solve the transform problem. But Booster’s considerations go beyond just implementation. Here is a comparison:
| Solution | Instrumentation API | Artifacts API |
|---|---|---|
| Pros |
|
|
| Cons |
|
|
Based on this analysis, we lean toward the Artifacts API approach. While the Instrumentation API may offer better Gradle cache support, many features are constrained by AGP’s current implementation. From our understanding of Booster’s user base, the Instrumentation API‘s current capabilities are far from meeting developer needs – especially for use cases that depend on intermediate build artifacts, where the Instrumentation API is extremely cumbersome. So Booster takes the developer’s perspective: minimize feature compromises while keeping migration costs low.
References
- Blog Link: https://johnsonlee.io/2023/05/29/how-booster-supports-agp-8.en/
- Copyright Declaration: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
