Flutter flutter.gradle分析
文章目录
所有的分析基于当前的 1.4.7 版本,flutter sdk 的版本更新可能会修改这个文件
1Flutter 1.4.7 • channel dev • https://github.com/flutter/flutter.git
2Framework • revision 1bfa2f2311 (3 days ago) • 2019-03-29 10:05:18 -0700
3Engine • revision c4d14a0071
4Tools • Dart 2.2.1 (build 2.2.1-dev.2.0 None)
这个文件是 sdk 中的 android 部分的配置文件文件,简单分析一下流程,以便于魔改或在项目中可以配置项目
gradle 使用的是 groovy 的语法,是一个 jvm 语言,在语法层级上兼容 Java 语法
换句话说 System.out.println("hello world");
这样的方法是可用的
分析 flutter 项目
项目 android/app/build.gradle 文件中都有定义
1def localProperties = new Properties()
2def localPropertiesFile = rootProject.file('local.properties')
3if (localPropertiesFile.exists()) {
4 localPropertiesFile.withReader('UTF-8') { reader ->
5 localProperties.load(reader)
6 }
7}
8
9def flutterRoot = localProperties.getProperty('flutter.sdk')
10if (flutterRoot == null) {
11 throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12}
13
14def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15if (flutterVersionCode == null) {
16 flutterVersionCode = '1'
17}
18
19def flutterVersionName = localProperties.getProperty('flutter.versionName')
20if (flutterVersionName == null) {
21 flutterVersionName = '1.0'
22}
23
24apply plugin: 'com.android.application'
25apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" // 这句代表了引入flutter.gradle到项目中,路径是
build.gradle 是 gradle 项目的主文件,关于 gradle 和相关说明可以自行搜索,这个体系很庞大,展开介绍不太现实
前面的基本都是 groovy 语法
def 是 groovy 中的关键字,可以简单理解为和 dart 中的 var 同义
读取 local.properties,然后在 properties 中查找 flutter 的 sdk 目录,如果没有就报错退出
然后是读取 properties 中定义的 versionCode 和 versionName
后面就是"引用" flutter.gradle 到项目中,通过这样的过程,flutter.gradle 的内容就被引入项目中了
flutter.gradle 的路径需要在 flutter sdk 目录下搜索 packages/flutter_tools/gradle/flutter.gradle
分析 flutter.gradle
开始是一些导包之类的相关代码
最后一行是一句关键的代码,引入插件FlutterPlugin
,这个是告诉 gradle,我需要引入这个插件
这个插件就定义在这个文件内
查看主要的方法也就是 apply 方法,可以简单的理解为回调方法,处理整个项目
1 @Override
2 void apply(Project project) {
3 // Add custom build types
4 // 定义一些buildType
5 project.android.buildTypes {
6 profile {
7 initWith debug //初始化参数来自于debug
8 if (it.hasProperty('matchingFallbacks')) {
9 matchingFallbacks = ['debug', 'release']
10 }
11 }
12 dynamicProfile {
13 initWith debug
14 if (it.hasProperty('matchingFallbacks')) {
15 matchingFallbacks = ['debug', 'release']
16 }
17 }
18 dynamicRelease {
19 initWith debug
20 if (it.hasProperty('matchingFallbacks')) {
21 matchingFallbacks = ['debug', 'release']
22 }
23 }
24 }
25
26 String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
27 // 查询flutter sdk的地址,如果没有定义,就查看FLUTTER_ROOT的环境变量,都没有就报错
28 if (flutterRootPath == null) {
29 throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment variable.")
30 }
31 flutterRoot = project.file(flutterRootPath)
32 if (!flutterRoot.isDirectory()) { //不是文件夹说明sdk地址不对,也报错
33 throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
34 }
35
36 // flutter的执行文件,windows执行bat,其他的执行flutter
37 String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
38 flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile();
39
40
41 if (project.hasProperty('localEngineOut')) { // 这里可以理解为自定义engine,应该是用于engine开发或深度定制engine的情况, 普通的flutter使用者直接看else
42 String engineOutPath = project.property('localEngineOut')
43 File engineOut = project.file(engineOutPath)
44 if (!engineOut.isDirectory()) {
45 throw new GradleException('localEngineOut must point to a local engine build')
46 }
47 flutterJar = Paths.get(engineOut.absolutePath, "flutter.jar").toFile()
48 if (!flutterJar.isFile()) {
49 throw new GradleException('Local engine build does not contain flutter.jar')
50 }
51
52 localEngine = engineOut.name
53 localEngineSrcPath = engineOut.parentFile.parent
54
55 project.dependencies {
56 if (project.getConfigurations().findByName("api")) {
57 api project.files(flutterJar)
58 } else {
59 compile project.files(flutterJar)
60 }
61 }
62 } else { //普通使用者
63 Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
64 String targetArch = 'arm'
65 if (project.hasProperty('target-platform') &&
66 project.property('target-platform') == 'android-arm64') {
67 // 这里是判断类型,如果有target-platform属性,且属性是arm64,则认为目标类型是arm64,否则默认是arm
68 targetArch = 'arm64'
69 }
70 debugFlutterJar = baseEnginePath.resolve("android-${targetArch}").resolve("flutter.jar").toFile()
71 profileFlutterJar = baseEnginePath.resolve("android-${targetArch}-profile").resolve("flutter.jar").toFile()
72 releaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-release").resolve("flutter.jar").toFile()
73 dynamicProfileFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-profile").resolve("flutter.jar").toFile()
74 dynamicReleaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-release").resolve("flutter.jar").toFile()
75
76 // 这些就是指定flutter.jar的类型
77
78 if (!debugFlutterJar.isFile()) {
79 project.exec {
80 executable flutterExecutable.absolutePath
81 args "--suppress-analytics"
82 args "precache"
83 }
84 if (!debugFlutterJar.isFile()) { //类型不对就报错
85 throw new GradleException("Unable to find flutter.jar in SDK: ${debugFlutterJar}")
86 }
87 }
88
89 // Add x86/x86_64 native library. Debug mode only, for now.
90 // 如果是debug的情况下,添加一个task用于copy x86/x86_64的so库到apk内
91 flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar")
92 Task flutterX86JarTask = project.tasks.create("${flutterBuildPrefix}X86Jar", Jar) {
93 destinationDir flutterX86Jar.parentFile
94 archiveName flutterX86Jar.name
95 from("${flutterRoot}/bin/cache/artifacts/engine/android-x86/libflutter.so") {
96 into "lib/x86"
97 }
98 from("${flutterRoot}/bin/cache/artifacts/engine/android-x64/libflutter.so") {
99 into "lib/x86_64"
100 }
101 }
102 // Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones
103 // added after applying the Flutter plugin.
104 project.android.buildTypes.each { addFlutterJarApiDependency(project, it, flutterX86JarTask) }
105 project.android.buildTypes.whenObjectAdded { addFlutterJarApiDependency(project, it, flutterX86JarTask) }
106 }
107
108 project.extensions.create("flutter", FlutterExtension)
109 project.afterEvaluate this.&addFlutterTask
110
111 // 这里是处理flutter插件, .flutter-plugins这个文件由flutter维护,来源于flutter项目中的pubspec.yaml
112 File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
113 Properties plugins = readPropertiesIfExist(pluginsFile)
114
115 plugins.each { name, _ ->
116 def pluginProject = project.rootProject.findProject(":$name")
117 if (pluginProject != null) {
118 // 这里两个循环就是将依赖需要的库引入当前项目内
119 project.dependencies {
120 if (project.getConfigurations().findByName("implementation")) {
121 implementation pluginProject
122 } else {
123 compile pluginProject
124 }
125 }
126 pluginProject.afterEvaluate {
127 pluginProject.android.buildTypes {
128 profile {
129 initWith debug
130 }
131 }
132 }
133 pluginProject.afterEvaluate this.&addFlutterJarCompileOnlyDependency
134 } else {
135 project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
136 }
137 }
138 }
我简单对于 apply 方法进行了分析加了一些注释
后记
很多东西需要对于 groovy 语法和 gradle 构建体系有所了解才能看懂,当然我也是萌新一枚,有错误或需要讨论可以留言
以上