We upgraded and adapted AGP 7.0 | gossip

theme: smartblue


Everybody, I wish you a happy new year in advance.

At the beginning of the year, we plan to upgrade apg, and then embrace jetpack compose!!

If you want to use comopse, you have two required options agp7 0 and kotlin version 1.5.31

Java11 configuration

Because apg7 0 needs to switch all module compilation environments to Java 11 version, but this place is prone to errors.

The first is the command line configuration. For mac users, the default java environment may be written to 1.8 What we need to do at this time is to delete the java configuration in bashprofile.

At the same time, it is best to use the command line java --version to try whether the output version is java11.

The configuration of as is relatively simple.

After these two configurations are completed, it should be OK to resynchronize the next project.


Before Are you ready to say goodbye to Transform now? The article simply expanded the Android components extension, and the new version replaced the extensions. What plug-ins were written before the project was upgraded and adapted this time? Do you want to use them for a long time? Try something new.


In the past, when writing android plug-ins, you often need to execute the afterEvaluate method of grade to obtain many android corresponding properties.

This time, in the v2 api, there are many different nodes. Let's do some different things at different stages.

For example, onVariants, beforevariants and finalizedsl are three different stages. Under normal circumstances, it is enough for us to choose onVariants.

Component Artifacts

demo address

Some of the core tasks in grade are tasks, but it is not as easy to write a Task as expected. Especially for a CacheableTask, it pays more attention to their input and output.

The working principle of build cache is to store compiled classes, test outputs and other building components in the cache, and consider all task inputs, including input file content, relevant class paths and task configuration.

Therefore, in AGP 7.0, this new api is provided to simplify the optimization of task, input and output parameters, so that we can focus more on what we want to change.

For example, APk,MANIFEST,MAPPING_FILE,BUNDLE,AAR or other compiled products, agp currently provides us with relatively few functions.

Another point is that if we want to know the input of a task, it is actually a very cumbersome process to obtain the corresponding path or source code without reading the source code. After that, the task should be inserted into the compilation process by changing dependent or finalized by.

So we have one of our protagonists, Artifacts, who is mainly responsible for helping us insert our task s into the compilation process, so that we can pay less attention to input and output.

          // Generate TaskProvider 
          val taskProvider = project.tasks.register(
          // After obtaining the artifacts of variant, convert the Task into what we want

This is the simple use of an official artifact. Through changes, we can easily complete a task that takes the merged Manifest as input and another Manifest file as output. And will be directly added to the compilation process, so we don't need to care about their pre and post tasks.

registerJavaGenerateTask is gone

Originally, on the api of v1, there was the method registerJavaGenerateTask, which can add some simple code generation operations. For example, R2 previously generated by j God is mounted by this method.

In this v2 version, I didn't find the corresponding api in the AndroidComponentsExtension, so I have to make one myself.

 public void registerJavaGeneratingTask(@NonNull Task task, @NonNull File... sourceFolders) {
     getVariantData().registerJavaGeneratingTask(task, sourceFolders);
 open fun registerJavaGeneratingTask(
    task: Task,
    generatedSourceFolders: Collection<File>
) {

    val fileTrees = extraGeneratedSourceFileTrees ?: mutableListOf<ConfigurableFileTree>().also {
        extraGeneratedSourceFileTrees = it

    for (f in generatedSourceFolders) {
        val fileTree = services.fileTree(f).builtBy(task)

I carefully observed the source code of registerJavaGenerateTask and found that only two relatively simple things were done. Mount the Task to the generateVariantResources Task, and then add the folder where the java class is generated to the sourceset. That's all.

sourcetSet is the compilation path of javac to convert java into class.

So it's relatively simple. We can simulate the original effect with the new api. We just need to find the mounted task and add the code to the sourceset of java and kotlin

fun Project.registerJavaGenerateTask(
    variant: String?,
    task: TaskProvider<out Task>,
    generatedSourceFolders: Collection<File>
) {
    if (variant.isNullOrEmpty().not()) {
        variant?.apply {
            // Because the task generation is completed after the configuration phase
            afterEvaluate {
            //  Get the latest version sourceSet
            val application = extensions.findByType(ApplicationExtension::class.java)
            application?.sourceSets {
                findByName(variant)?.apply {
                    generatedSourceFolders.forEach {

This is the main code for the upgrade adaptation. In fact, the amount of code is not much. But there is a hole in the file. Before, because of laziness, I directly used the api of setSrcDirs, so the file was overwritten. As a result, part of the code is not compiled into class, resulting in a classnotfound exception.


Obtain the applicationId. Our plug-in has the judgment of the application id, and then adjust different manifest pleaeholder. The logic is relatively simple, just switching the new version of api.

  if (variant is ApplicationVariant) {
    val applicationId = variant.applicationId.get()
      variant.manifestPlaceholders.put("xxxxx", applicationId)

Insert a new string or values into the resValue. It is also the original ability, but it needs a small adaptation and replacement of the new version.

private fun addAPGClassFile(config: Variant, key: String, value: String) {
    val resValue = ResValue(value)
    val reskey = config.makeResValueKey("string", key)
    config.resValues.put(reskey, resValue)

Start configuration cache

The operation of enabling the configuration cache is essentially in the gradle The environment variable {org. Is set in the properties file gradle. unsafe. configuration-cache=true.


AGP is updated every year for us. We will encounter some new and interesting APIs and new writing methods. In addition, every new version of AGP has changes and optimizations for compilation.

In fact, if you are interested, you can try a small upgrade of your application. In addition, I really can't make up the number of words. I will make it next time.

Added by enfys on Sun, 06 Mar 2022 05:11:50 +0200