Flutter 1.4.7 • channel dev • https://github.com/flutter/flutter.git
Framework • revision 1bfa2f2311 (3 days ago) • 2019-03-29 10:05:18 -0700
Engine • revision c4d14a0071
Tools • Dart 2.2.1 (build 2.2.1-dev.2.0 None)
这个文件是 sdk 中的 android 部分的配置文件文件,简单分析一下流程,以便于魔改或在项目中可以配置项目
gradle 使用的是 groovy 的语法,是一个 jvm 语言,在语法层级上兼容 Java 语法
换句话说 System.out.println("hello world");
这样的方法是可用的
项目 android/app/build.gradle 文件中都有定义
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply 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
开始是一些导包之类的相关代码
最后一行是一句关键的代码,引入插件FlutterPlugin
,这个是告诉 gradle,我需要引入这个插件
这个插件就定义在这个文件内
查看主要的方法也就是 apply 方法,可以简单的理解为回调方法,处理整个项目
@Override
void apply(Project project) {
// Add custom build types
// 定义一些buildType
project.android.buildTypes {
profile {
initWith debug //初始化参数来自于debug
if (it.hasProperty('matchingFallbacks')) {
matchingFallbacks = ['debug', 'release']
}
}
dynamicProfile {
initWith debug
if (it.hasProperty('matchingFallbacks')) {
matchingFallbacks = ['debug', 'release']
}
}
dynamicRelease {
initWith debug
if (it.hasProperty('matchingFallbacks')) {
matchingFallbacks = ['debug', 'release']
}
}
}
String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
// 查询flutter sdk的地址,如果没有定义,就查看FLUTTER_ROOT的环境变量,都没有就报错
if (flutterRootPath == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment variable.")
}
flutterRoot = project.file(flutterRootPath)
if (!flutterRoot.isDirectory()) { //不是文件夹说明sdk地址不对,也报错
throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
}
// flutter的执行文件,windows执行bat,其他的执行flutter
String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile();
if (project.hasProperty('localEngineOut')) { // 这里可以理解为自定义engine,应该是用于engine开发或深度定制engine的情况, 普通的flutter使用者直接看else
String engineOutPath = project.property('localEngineOut')
File engineOut = project.file(engineOutPath)
if (!engineOut.isDirectory()) {
throw new GradleException('localEngineOut must point to a local engine build')
}
flutterJar = Paths.get(engineOut.absolutePath, "flutter.jar").toFile()
if (!flutterJar.isFile()) {
throw new GradleException('Local engine build does not contain flutter.jar')
}
localEngine = engineOut.name
localEngineSrcPath = engineOut.parentFile.parent
project.dependencies {
if (project.getConfigurations().findByName("api")) {
api project.files(flutterJar)
} else {
compile project.files(flutterJar)
}
}
} else { //普通使用者
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
String targetArch = 'arm'
if (project.hasProperty('target-platform') &&
project.property('target-platform') == 'android-arm64') {
// 这里是判断类型,如果有target-platform属性,且属性是arm64,则认为目标类型是arm64,否则默认是arm
targetArch = 'arm64'
}
debugFlutterJar = baseEnginePath.resolve("android-${targetArch}").resolve("flutter.jar").toFile()
profileFlutterJar = baseEnginePath.resolve("android-${targetArch}-profile").resolve("flutter.jar").toFile()
releaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-release").resolve("flutter.jar").toFile()
dynamicProfileFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-profile").resolve("flutter.jar").toFile()
dynamicReleaseFlutterJar = baseEnginePath.resolve("android-${targetArch}-dynamic-release").resolve("flutter.jar").toFile()
// 这些就是指定flutter.jar的类型
if (!debugFlutterJar.isFile()) {
project.exec {
executable flutterExecutable.absolutePath
args "--suppress-analytics"
args "precache"
}
if (!debugFlutterJar.isFile()) { //类型不对就报错
throw new GradleException("Unable to find flutter.jar in SDK: ${debugFlutterJar}")
}
}
// Add x86/x86_64 native library. Debug mode only, for now.
// 如果是debug的情况下,添加一个task用于copy x86/x86_64的so库到apk内
flutterX86Jar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/flutter-x86.jar")
Task flutterX86JarTask = project.tasks.create("${flutterBuildPrefix}X86Jar", Jar) {
destinationDir flutterX86Jar.parentFile
archiveName flutterX86Jar.name
from("${flutterRoot}/bin/cache/artifacts/engine/android-x86/libflutter.so") {
into "lib/x86"
}
from("${flutterRoot}/bin/cache/artifacts/engine/android-x64/libflutter.so") {
into "lib/x86_64"
}
}
// Add flutter.jar dependencies to all Api configurations, including custom ones
// added after applying the Flutter plugin.
project.android.buildTypes.each { addFlutterJarApiDependency(project, it, flutterX86JarTask) }
project.android.buildTypes.whenObjectAdded { addFlutterJarApiDependency(project, it, flutterX86JarTask) }
}
project.extensions.create("flutter", FlutterExtension)
project.afterEvaluate this.&addFlutterTask
// 这里是处理flutter插件, .flutter-plugins这个文件由flutter维护,来源于flutter项目中的pubspec.yaml
File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
Properties plugins = readPropertiesIfExist(pluginsFile)
plugins.each { name, _ ->
def pluginProject = project.rootProject.findProject(":$name")
if (pluginProject != null) {
// 这里两个循环就是将依赖需要的库引入当前项目内
project.dependencies {
if (project.getConfigurations().findByName("implementation")) {
implementation pluginProject
} else {
compile pluginProject
}
}
pluginProject.afterEvaluate {
pluginProject.android.buildTypes {
profile {
initWith debug
}
}
}
pluginProject.afterEvaluate this.&addFlutterJarCompileOnlyDependency
} else {
project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
}
}
}
我简单对于 apply 方法进行了分析加了一些注释
很多东西需要对于 groovy 语法和 gradle 构建体系有所了解才能看懂,当然我也是萌新一枚,有错误或需要讨论可以留言
以上