upgrade

Early happy New Year to you all, gentlemen.

At the beginning of the year, we’re going to update APG so that we can embrace Jetpack Compose!!

To use COMopse there are two mandatory options agP7.0 and Kotlin version 1.5.31.

Java11 configuration

Apg7.0 requires all module compilation environments to be switched to java11, which is error prone.

The first is the command line configuration, which for MAC users may write the default Java environment to 1.8. All we need to do at this point is delete the Java configuration in the BashProfile.

It is also best to use the command line Java –version to check whether the output version is Java11.

As configuration is relatively simple.

After completing these two configurations, it should be ok to resynchronize the project.

AndroidComponentsExtension

Are you ready to say goodbye to Transform? Launched AndroidComponentsExtension under article is simple, the new version to replace the extensions. What plug-ins were written before the project was upgraded and adapted this time? I think it will not take long to use the new one, so I will try new things.

onVariants

In the past, many android plugins had to be evaluated after Gralde’s afterEvaluate method was executed to obtain a number of android attributes.

This time in the V2 API, there are a lot of different nodes that let us do different things at different stages.

For example onVariants beforeVariants, finalizeDsl these three different stages, under normal circumstances we choose onVariants is enough.

Component Artifacts

The demo address

Part of the core of Gralde is Task, but writing a Task well is not as easy as you might think. A CacheableTask in particular focuses more on their inputs and outputs.

The Build cache works by storing compiled classes, test output, and other build artifacts in the cache, taking into account all task inputs, including input file contents, associated classpath, and task configuration.

So in AGP 7.0, the new API provides us with a way to simplify the optimization of task, input and output parameters, allowing us to focus more on what we want to change.

Such as APk,MANIFEST,MAPPING_FILE,BUNDLE,AAR, and other compilations, AGP currently provides a relatively small amount of functionality.

Another point is that if we want to know the input of a task without reading the source code, then obtaining the corresponding path or source code is a very tedious process. The task is then inserted into the compilation process by changing dependon or finalizedBy, etc.

So one of our main Artifacts for this time is to help us insert our tasks into the compilation process so that we pay as little attention to the inputs and outputs as possible.

Var TaskProvider = project.tasks. Register ("manifestCopy${varie. name}Task", ManifestSampleTask: : class. Java) / / Task after obtaining the variant artifacts into what we want variant.artifacts.use(taskProvider).wiredWithFiles( ManifestSampleTask::mergedManifest, ManifestSampleTask::outputManifest ).toTransform(SingleArtifact.MERGED_MANIFEST)Copy the code

This is a simple use of official Artifacts, which can be changed to easily complete a task that takes the merged Manifest as input and another Manifest file as output. They are added directly to the build process, so we don’t need to worry about their pre – and post-tasks.

RegisterJavaGenerateTask didn’t

RegisterJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask = registerJavaGenerateTask

The v2 version I couldn’t find the corresponding API in AndroidComponentsExtension, so can only be friends, no yourself an out.

@Override
 public void registerJavaGeneratingTask(@NonNull Task task, @NonNull File... sourceFolders) {
     getVariantData().registerJavaGeneratingTask(task, sourceFolders);
 }
 open fun registerJavaGeneratingTask(
    task: Task,
    generatedSourceFolders: Collection<File>
) {
    @Suppress("DEPRECATION")
    taskContainer.sourceGenTask.dependsOn(task)

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

    for (f in generatedSourceFolders) {
        val fileTree = services.fileTree(f).builtBy(task)
        fileTrees.add(fileTree)
    }
    addJavaSourceFoldersToModel(generatedSourceFolders)
}
Copy the code

I took a close look at the source code for registerJavaGenerateTask and found that it did only two relatively simple things. Mount the Task to the generateVariantResources Task, then add the folder that generated the Java classes to sourcetSet, and you’re done.

SourcetSet is the javac compilation path for converting Java to a class.

So it’s relatively simple, we can just simulate the original effect with the new API, we just need to find the mount task and add the code to Java and Kotlin sourceset

fun Project.registerJavaGenerateTask(
    variant: String? , task:TaskProvider<out Task>,
    generatedSourceFolders: Collection<File>) {
    if(variant.isNullOrEmpty().not()) { variant? .apply {// Because the task generation is done after the configuration phaseafterEvaluate { findJavaGenerateTask(variant)? .dependsOn(task) }// Get the latest version sourceSet
            val application = extensions.findByType(ApplicationExtension::class.java) application? .sourceSets { findByName(variant)? .apply { generatedSourceFolders.forEach { java.srcDir(it) kotlin.srcDir(it) } } } } } }Copy the code

This upgrade adaptation of the main code is this, in fact, the amount of code is not much. But there is a hole in the file, because I used setSrcDirs directly because I was lazy, so the file is overwritten. Part of the code was not compiled to class, resulting in the ClassNotFound exception.

other

Get the applicationId, which is determined by the applicationId in our plug-in, and then adjust to the different manifest pleaceholder. The logic is simple, just switch the new version of the API.

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

Insert a new string or values for resValue. Is also the original ability, but to the new version of a small adaptation and replacement.

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

Start the configuration cache

Enable configuration cache operation, is essentially in the project of gradle. The properties file set the environment variable org. Gradle. Unsafe. The configuration – cache = true.

At the end

AGP is updated every year for us, with some interesting new apis and new ways of writing. In addition, each new version of AGP has changes and optimizations for compilation.

You are interested in actually can try their own application for a small upgrade. In addition, I really can not make up the number of words, next time must ah.