if (project.hasProperty(‘extra-gen-snapshot-options’)) {
extraGenSnapshotOptionsValue = project.property(‘extra-gen-snapshot-options’)
}
String splitDebugInfoValue = null
if (project.hasProperty(‘split-debug-info’)) {
splitDebugInfoValue = project.property(‘split-debug-info’)
}
Boolean dartObfuscationValue = false
if (project.hasProperty(‘dart-obfuscation’)) {
dartObfuscationValue = project.property(‘dart-obfuscation’).toBoolean();
}
Boolean treeShakeIconsOptionsValue = false
if (project.hasProperty(‘tree-shake-icons’)) {
treeShakeIconsOptionsValue = project.property(‘tree-shake-icons’).toBoolean()
}
String dartDefinesValue = null
if (project.hasProperty(‘dart-defines’)) {
dartDefinesValue = project.property(‘dart-defines’)
}
String bundleSkSLPathValue;
if (project.hasProperty(‘bundle-sksl-path’)) {
bundleSkSLPathValue = project.property(‘bundle-sksl-path’)
}
String performanceMeasurementFileValue;
if (project.hasProperty(‘performance-measurement-file’)) {
performanceMeasurementFileValue = project.property(‘performance-measurement-file’)
}
String codeSizeDirectoryValue;
if (project.hasProperty(‘code-size-directory’)) {
codeSizeDirectoryValue = project.property(‘code-size-directory’)
}
Boolean deferredComponentsValue = false
if (project.hasProperty(‘deferred-components’)) {
deferredComponentsValue = project.property(‘deferred-components’).toBoolean()
}
Boolean validateDeferredComponentsValue = true
if (project.hasProperty(‘validate-deferred-components’)) {
validateDeferredComponentsValue = project.property(‘validate-deferred-components’).toBoolean()
}
def targetPlatforms = getTargetPlatforms()
…
}
可以看到,addFlutterTasks 方法的第一部分比较简单,基本都是从 Project 中读取各自配置属性供后续步骤使用。所以我们接着继续看 addFlutterTasks 这个方法步骤 1 之后的部分:
private void addFlutterTasks(Project project) {
//一堆属性获取与赋值操作
//…
//1、定义 addFlutterDeps 箭头函数,参数variant为标准构建对应的构建类型
def addFlutterDeps = { variant ->
if (shouldSplitPerAbi()) {
//2、常规操作:如果是构建多个变体apk模式就处理vc问题
variant.outputs.each { output ->
//由于GP商店不允许同一个应用的多个APK全都具有相同的版本信息,因此在上传到Play商店之前,您需要确保每个APK都有自己唯一的versionCode,这里就是做这个事情的。
//具体可以看官方文档 https://developer.android.com/studio/build/configure-apk-splits
def abiVersionCode = ABI_VERSION.get(output.getFilter(OutputFile.ABI))
if (abiVersionCode != null) {
output.versionCodeOverride =
abiVersionCode * 1000 + variant.versionCode
}
}
}
//3、获取编译类型,variantBuildMode值为debug、profile、release之一
String variantBuildMode = buildModeFor(variant.buildType)
//4、依据参数生成一个task名字,譬如这里的compileFlutterBuildDebug、compileFlutterBuildProfile、compileFlutterBuildRelease
String taskName = toCammelCase([“compile”, FLUTTER_BUILD_PREFIX, variant.name])
//5、给当前project创建compileFlutterBuildDebug、compileFlutterBuildProfile、compileFlutterBuildRelease Task
//实现为FlutterTask,主要用来编译Flutter代码,这个task稍后单独分析
FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
//各种task属性赋值操作,基本都来自上面的属性获取或者匹配分析
flutterRoot this.flutterRoot
flutterExecutable this.flutterExecutable
buildMode variantBuildMode
localEngine this.localEngine
localEngineSrcPath this.localEngineSrcPath
//默认dart入口lib/main.dart、可以通过target属性自定义指向
targetPath getFlutterTarget()
verbose isVerbose()
fastStart isFastStart()
fileSystemRoots fileSystemRootsValue
fileSystemScheme fileSystemSchemeValue
trackWidgetCreation trackWidgetCreationValue
targetPlatformValues = targetPlatforms
sourceDir getFlutterSourceDirectory()
//学到一个小技能,原来中间API是AndroidProject.FD_INTERMEDIATES,这也是flutter中间产物目录
intermediateDir project.file(“ p r o j e c t . b u i l d D i r / {project.buildDir}/ project.buildDir/{AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/”)
extraFrontEndOptions extraFrontEndOptionsValue
extraGenSnapshotOptions extraGenSnapshotOptionsValue
splitDebugInfo splitDebugInfoValue
treeShakeIcons treeShakeIconsOptionsValue
dartObfuscation dartObfuscationValue
dartDefines dartDefinesValue
bundleSkSLPath bundleSkSLPathValue
performanceMeasurementFile performanceMeasurementFileValue
codeSizeDirectory codeSizeDirectoryValue
deferredComponents deferredComponentsValue
validateDeferredComponents validateDeferredComponentsValue
//最后做一波权限相关处理
doLast {
project.exec {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine(‘cmd’, ‘/c’, “attrib -r ${assetsDirectory}/* /s”)
} else {
commandLine(‘chmod’, ‘-R’, ‘u+w’, assetsDirectory)
}
}
}
}
//项目构建中间产物的文件,也就是根目录下build/intermediates/flutter/debug/libs.jar文件
File libJar = project.file(“ p r o j e c t . b u i l d D i r / {project.buildDir}/ project.buildDir/{AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar”)
//6、创建packLibsFlutterBuildProfile、packLibsFlutterBuildDebug、packLibsFlutterBuildRelease任务,主要是产物的复制挪位置操作,Jar 类型的 task
//作用就是把build/intermediates/flutter/debug/下依据abi生成的app.so通过jar命令打包成build/intermediates/flutter/debug/libs.jar
Task packFlutterAppAotTask = project.tasks.create(name: “packLibs F L U T T E R B U I L D P R E F I X {FLUTTER_BUILD_PREFIX} FLUTTERBUILDPREFIX{variant.name.capitalize()}”, type: Jar) {
//目标路径为build/intermediates/flutter/debug目录
destinationDir libJar.parentFile
//文件名为libs.jar
archiveName libJar.name
//依赖前面步骤5定义的compileFlutterBuildDebug,也就是说,这个task基本作用是产物处理
dependsOn compileTask
//targetPlatforms取值为android-arm、android-arm64、android-x86、android-x64
targetPlatforms.each { targetPlatform ->
//abi取值为armeabi-v7a、arm64-v8a、x86、x86_64
String abi = PLATFORM_ARCH_MAP[targetPlatform]
//数据来源来自步骤5的compileFlutterBuildDebug任务中间产物目录
//即把build/intermediates/flutter/debug/下依据abi生成的app.so通过jar命令打包成一个build/intermediates/flutter/debug/libs.jar文件
from(“ c o m p i l e T a s k . i n t e r m e d i a t e D i r / {compileTask.intermediateDir}/ compi