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
- AGP6+:build\intermediates\
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
// 其他待完善