概述

#

要构建 Flutter Android 应用,必须应用 Flutter 的 Gradle 插件。过去,这通常通过 Gradle 的 旧式命令式 apply 脚本方法 以命令式的方式完成。

在 Flutter 3.16 中,已添加对使用 Gradle 的 声明式 plugins {} 块(也称为 Plugin DSL)应用这些插件的支持,现在这已是推荐的做法。自 Flutter 3.16 起,使用 flutter create 生成的项目会使用 Plugin DSL 来应用 Gradle 插件。在 Flutter 3.16 之前的版本创建的项目需要手动迁移。

使用 plugins {} 块应用 Gradle 插件会执行与之前相同的代码,并且应该会生成相同的应用二进制文件。

要了解新的 Plugin DSL 语法相对于旧式 apply 脚本语法的优势,请参阅 Gradle 文档

将应用生态系统迁移到使用新方法,也将使 Flutter 团队更容易开发 Flutter 的 Gradle 插件,并支持未来令人兴奋的新功能,例如在 Gradle 构建脚本中使用 Kotlin 而不是 Groovy。

迁移

#

android/settings.gradle

#

首先,找到项目当前使用的 Android Gradle Plugin (AGP) 和 Kotlin 的版本。除非它们已被移动,否则它们很可能定义在 <app-src>/android/build.gradle 文件的 buildscript 块中。例如,考虑此更改之前使用新 Flutter 应用创建的 build.gradle 文件

groovy
buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.3.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

AGP 版本是行 classpath 'com.android.tools.build:gradle:7.3.0' 末尾的数字,在本例中为 7.3.0。同样,Kotlin 版本在行 ext.kotlin_version = '1.7.10' 的末尾,在本例中为 1.7.10

接下来,用以下内容替换 <app-src>/android/settings.gradle 的内容,记住用先前确定的值替换 {agpVersion}{kotlinVersion}

groovy
pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }()

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0" // apply true
    id "com.android.application" version "{agpVersion}" apply false
    id "org.jetbrains.kotlin.android" version "{kotlinVersion}" apply false
}

include ":app"

如果您对此文件进行了一些更改,请确保它们位于 pluginManagement {}plugins {} 块之后,因为 Gradle 会强制要求这些块之前不能放置任何其他代码。

Flutter Gradle 插件 (dev.flutter.flutter-plugin-loader) 不应设置为 apply false(默认值为 true),或者应明确设置为 true。

android/build.gradle

#

<app-src/android/build.gradle 中删除整个 buildscript

groovy
buildscript {
    ext.kotlin_version = '{kotlinVersion}'
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:gradle-plugin:$kotlin_version"
    }
}

该文件最终可能如下所示

groovy
allprojects {
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

tasks.register("clean", Delete) {
    delete rootProject.buildDir
}

android/app/build.gradle

#

默认情况下位于 <app-src>/android/app/build.gradle 中的代码也需要进行以下更改。首先,删除以下两个使用旧式命令式 apply 方法的代码块

groovy
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.")
}
groovy
apply plugin: 'com.android.application'
apply plugin: 'com.jetbrains.kotlin.android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

现在再次应用插件,但这次使用 Plugin DSL 语法。在文件的最顶部添加

groovy
plugins {
    id "com.android.application"
    id "kotlin-android"
    id "dev.flutter.flutter-gradle-plugin"
}

"dev.flutter.flutter-gradle-plugin" 是项目 Flutter Gradle 插件,它与在 settings.gradle(.kts) 中应用的字符串("dev.flutter.flutter-plugin-loader")不同。

最后,如果您的 dependencies 块包含对 "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 的依赖,请删除该依赖。

groovy
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

如果这是 dependencies 块中的唯一依赖项,则可以完全删除该块。

验证

#

执行 flutter run 以确认您的应用在连接的 Android 设备或模拟器上能够成功构建和启动。

示例

#

Google Mobile Services 和 Crashlytics

#

如果您的应用使用了 Google Mobile Services 和 Crashlytics,请从 <app-src>/android/build.gradle 中删除以下行

groovy
buildscript {
    // ...

    dependencies {
        // ...
        classpath "com.google.gms:google-services:4.4.0"
        classpath "com.google.firebase:firebase-crashlytics-gradle:2.9.9"
    }
}

然后从 <app-src>/android/app/build.gradle 中删除这两行

groovy
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

要迁移到 GMS 和 Crashlytics 插件的新声明式 apply 语法,请将它们添加到应用 <app-src>/android/settings.gradle 文件的 plugins 块中。添加的内容应与以下内容类似,但使用您期望的版本,可能与您从 <app-src>/android/build.gradle 文件中删除的版本匹配。

groovy
plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "{agpVersion}" apply false
    id "org.jetbrains.kotlin.android" version "{kotlinVersion}" apply false
    id "com.google.gms.google-services" version "4.4.0" apply false
    id "com.google.firebase.crashlytics" version "2.9.9" apply false
}

将以下行添加到 <app-src>/android/app/build.gradle

groovy
plugins {
    id "com.android.application"
    id "dev.flutter.flutter-gradle-plugin"
    id "org.jetbrains.kotlin.android"
    id "com.google.gms.google-services"
    id "com.google.firebase.crashlytics"
}

时间线

#

稳定版支持:3.16.0 稳定版推荐:3.19.0

参考资料

#

flutter create 生成的 Gradle 构建文件在不同 Flutter 版本之间存在差异。有关详细概述,请参阅 issue #135392。您应该考虑使用最新的构建文件版本。