适配 AGP8.5 版本,转换过程(四)

发布于:2025-03-29 ⋅ 阅读:(32) ⋅ 点赞:(0)

在这里插入图片描述

Public Artifact

支持的组件输出、输入类型

  • FILE:文件
  • DIRECTORY:目录

SingleArtifact

支持的转换类型:(列举几个常用的)

  • APK:安装包路径
  • MERGED_MANIFEST:Manifest 文件
  • OBFUSCATION_MAPPING_FILE:mapping.txt 文件
  • AAR:aar 包
  • ASSETS:assets 文件
  • MERGED_NATIVE_LIBS:so 库文件

1. 立刻终止构建

AGP7+

之前我是这样直接抛出异常,还是比较快终止构建,到 AGP8 之后发现不行了,默认开启即使抛出异常也会继续执行剩下的 Task

class ExceptionHelper {

    companion object {

        @JvmStatic
        fun throwExecution(msg: String) {
            throw GradleException(msg)
            System.exit(-1)
        }
    }
}

AGP8+

可以在插件初始化时设置

//抛出异常时立刻停止构建,其实 AGP 低版本也有这个
project.gradle.startParameter.isContinueOnFailure = false

在这里插入图片描述

2. Manifest 合并

AGP+7

  • 获取所有 Task project.tasks.findAll().iterator()
  • 遍历、判断 Task name,拿到特定任务(如 processReleaseManifest、mergeReleaseAssets)
  • 为特定 Task 添加前后执行逻辑(设置 doFirst 、doLast)
project.afterEvaluate {
	expendTask()
}

private List expendTask() {
    Iterator<Task> eIterator = project.tasks.findAll().iterator()
    while (eIterator.hasNext()) {
        Task theTask = eIterator.next()
        switch (CommUtils.judgeTaskType(theTask.name)) {
            case TaskType.TASK_PROCESS_RELEASE_MANIFEST:
                theTask.doLast {
                }
                break
        }
    }
}

AGP8+

  • 指定输入:@get:InputFile
  • 指定输出:@get:OutputFile(一定要输出,否则下一个 Transform 没有输入)
  • 指定 SingleArtifact:SingleArtifact.MERGED_MANIFEST
private fun registerTransform(project: Project) {
    val androidExt = project.extensions.getByType(AndroidComponentsExtension::class.java)
    androidExt.onVariants { variant ->
    	//处理 manifest 文件
        val manifestUpdater = project.tasks.register(
            variant.name + "ManifestTransformerTask", ManifestTransformerTask::class.java
        ) {}
        variant.artifacts.use(manifestUpdater).wiredWithFiles(
            ManifestTransformerTask::mergedManifest,
            ManifestTransformerTask::updatedManifest
        ).toTransform(SingleArtifact.MERGED_MANIFEST)
    }
}
abstract class ManifestTransformerTask : DefaultTask() {
    @get:InputFile
    @get:PathSensitive(PathSensitivity.NONE)
    abstract val mergedManifest: RegularFileProperty

    @get:OutputFile
    abstract val updatedManifest: RegularFileProperty

    @TaskAction
    fun taskAction() {
        println("ManifestTransformerTask run")
        var manifest = mergedManifest.asFile.get().readText()
        //todo:解析 manifest  并做相应修改或查找,最后输出更新

        updatedManifest.get().asFile.writeText(manifest)
    }
}

3. Assets 合并

AGP7+

project.afterEvaluate {
	expendTask()
}

private List expendTask() {
    Iterator<Task> eIterator = project.tasks.findAll().iterator()
    while (eIterator.hasNext()) {
        Task theTask = eIterator.next()
        switch (CommUtils.judgeTaskType(theTask.name)) {
            case TaskType.TASK_MERGE_RELEASE_ASSETS:
                theTask.doLast {
                }
                break
        }
    }
}

AGP8+

  • 指定输入:@get:inputDir
  • 指定输出:@get:outputDir(一定要输出,否则下一个 Transform 没有输入)
  • 指定 SingleArtifact:SingleArtifact.ASSETS
private fun registerTransform(project: Project) {
    project.plugins.withType(AppPlugin::class.java) {
        val appExt =
            project.extensions.getByType(ApplicationAndroidComponentsExtension::class.java)
        appExt.onVariants { variant ->
            //assets merge
            val assetsTaskProvider =
                project.tasks.register(
                    variant.name + ConstantStr.PREFIX_TRANSFORM + "AssetsTransformerTask",
                    AssetsTransformerTask::class.java
                )
            variant.artifacts.use(assetsTaskProvider)
                .wiredWithDirectories(
                    AssetsTransformerTask::inputDir,
                    AssetsTransformerTask::outputDir
                ).toTransform(SingleArtifact.ASSETS)
        }
    }
}

注意点:

  • transform 前清空输出目录:PluginFileUtils.deleteFolder(outFileDir)
  • assets 路径变更:
    • AGP6+:build\intermediates\merged_assets
    • AGP7+、8+:build\intermediates\assets\release\mergeReleaseAssets
abstract class AssetsTransformerTask : DefaultTask() {
    @get:InputDirectory
    abstract val inputDir: DirectoryProperty

    @get:OutputDirectory
    abstract val outputDir: DirectoryProperty

    @TaskAction
    fun taskAction() {
        val outFileDir = outputDir.asFile.get()
        if (outFileDir.exists()) {
        	//否则报错:文件已存在(不 clean build 目录情况下)
            CmdColorPrintUtils.outputYellow("重新打包前需要先清空目录:\n\t ${outFileDir.absolutePath}")
            PluginFileUtils.deleteFolder(outFileDir)
        }
   
        // We must copy the contents of the input directory to the output directory before our transformation
        inputDir.get().asFile.copyRecursively(outputDir.get().asFile)

        println("AssetsTransformerTask outputDir: ${outputDir.asFile.get().absolutePath}")

        outputDir.asFileTree.forEach {
            println("AssetsTransformerTask output =${it.absolutePath}")
        }
    }
}

如果注册了 assets Transform,那么 assets 输出目录下会有多个目录:

  • mergeReleaseAssets:系统默认名称
  • 其他自定义名称:例如我插件的 releaseDnAssetsTransformerTask

在这里插入图片描述

// 其他待完善