构建并发布 Android 应用

在典型的开发周期中,你可以使用命令行中的 flutter run 或使用 IDE 中的运行调试选项来测试应用。默认情况下,Flutter 会构建应用的调试版本。

当你准备为应用准备发布版本时,例如要发布到 Google Play 商店,此页面可以提供帮助。在发布之前,你可能希望对应用进行一些润色。此页面涵盖以下主题

添加启动器图标

当创建新的 Flutter 应用时,它有一个默认启动器图标。要自定义此图标,你可能希望查看 flutter_launcher_icons 包。

或者,你可以使用以下步骤手动进行

  1. 查看 Material Design 产品图标 指南以了解图标设计。

  2. [project]/android/app/src/main/res/ 目录中,将图标文件放置在使用 配置限定符命名的文件夹中。默认的 mipmap- 文件夹演示了正确的命名约定。

  3. AndroidManifest.xml 中,更新 application 标记的 android:icon 属性,以引用上一步中的图标(例如,<application android:icon="@mipmap/ic_launcher" ...)。

  4. 要验证是否已替换图标,请运行应用并检查启动器中的应用图标。

启用 Material Components

如果你的应用使用 平台视图,你可能希望按照 Android 入门指南 中所述的步骤启用 Material Components。

例如

  1. <my-app>/android/app/build.gradle 中添加对 Android Material 的依赖
dependencies {
    // ...
    implementation 'com.google.android.material:material:<version>'
    // ...
}

要了解最新版本,请访问 Google Maven

  1. <my-app>/android/app/src/main/res/values/styles.xml 中设置浅色主题
-<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
+<style name="NormalTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
  1. <my-app>/android/app/src/main/res/values-night/styles.xml 中设置深色主题
-<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
+<style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">

签名应用

要在 Play 商店中发布,你需要使用数字证书对应用进行签名。

Android 使用两个签名密钥:上传应用签名

  • 开发者将使用上传密钥签名的 .aab.apk 文件上传到 Play 商店。
  • 最终用户下载使用应用签名密钥签名的 .apk 文件。

要创建应用签名密钥,请按照 官方 Play 商店文档 中所述使用 Play 应用签名。

要签名您的应用,请使用以下说明。

创建上传密钥库

如果您有现有密钥库,请跳至下一步。如果没有,请使用以下方法之一创建一个

  1. 按照 Android Studio 密钥生成步骤 进行操作
  2. 在命令行中运行以下命令

    在 macOS 或 Linux 上,使用以下命令

    keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \
            -keysize 2048 -validity 10000 -alias upload
    

    在 Windows 上,在 PowerShell 中使用以下命令

    keytool -genkey -v -keystore %userprofile%\upload-keystore.jks ^
            -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 ^
            -alias upload
    

    此命令将 upload-keystore.jks 文件存储在您的主目录中。如果您想将其存储在其他位置,请更改传递给 -keystore 参数的参数。但是,请保持 keystore 文件私有;不要将其检入公共源代码管理!

从应用中引用密钥库

创建一个名为 [项目]/android/key.properties 的文件,其中包含对密钥库的引用。不要包含尖括号 (< >)。它们表示文本用作值的占位符。

storePassword=<password-from-previous-step>
keyPassword=<password-from-previous-step>
keyAlias=upload
storeFile=<keystore-file-location>

在 macOS 上,storeFile 可能位于 /Users/<用户名>/upload-keystore.jks,在 Windows 上可能位于 C:\\Users\\<用户名>\\upload-keystore.jks

在 gradle 中配置签名

通过编辑 [项目]/android/app/build.gradle 文件,配置 gradle 在发布模式下构建应用时使用上传密钥。

  1. android 块之前添加属性文件中的密钥库信息

       def keystoreProperties = new Properties()
       def keystorePropertiesFile = rootProject.file('key.properties')
       if (keystorePropertiesFile.exists()) {
           keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
       }
    
       android {
             ...
       }
    

    key.properties 文件加载到 keystoreProperties 对象中。

  2. 找到 buildTypes

       buildTypes {
           release {
               // TODO: Add your own signing config for the release build.
               // Signing with the debug keys for now,
               // so `flutter run --release` works.
               signingConfig signingConfigs.debug
           }
       }
    

    并用以下签名配置信息替换它

       signingConfigs {
           release {
               keyAlias keystoreProperties['keyAlias']
               keyPassword keystoreProperties['keyPassword']
               storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
               storePassword keystoreProperties['storePassword']
           }
       }
       buildTypes {
           release {
               signingConfig signingConfigs.release
           }
       }
    

现在会自动对应用的发布版本进行签名。

有关签名应用的更多信息,请查看 developer.android.com 上的 为应用签名

使用 R8 压缩代码

R8 是 Google 推出的新代码精简器,在构建发布 APK 或 AAB 时默认启用。要禁用 R8,请将 --no-shrink 标志传递给 flutter build apkflutter build appbundle

启用多 dex 支持

在编写大型应用或使用大型插件时,如果针对的最低 API 为 20 或更低,则可能会遇到 Android 64k 方法的 dex 限制。在使用未启用精简的 flutter run 运行应用的调试版本时,也可能会遇到这种情况。

Flutter 工具支持轻松启用多 dex。最简单的方法是在提示时选择加入多 dex 支持。该工具会检测到多 dex 构建错误,并在对 Android 项目进行更改之前询问。选择加入后,Flutter 可以自动依赖 androidx.multidex:multidex,并使用生成的 FlutterMultiDexApplication 作为项目的应用程序。

当您尝试使用 IDE 中的运行调试选项构建并运行应用时,您的构建可能会失败,并显示以下消息

screenshot of build failure because Multidex support is required

要从命令行启用多 dex,请运行 flutter run --debug 并选择一个 Android 设备

screenshot of selecting an Android device

在提示时,输入 y。Flutter 工具会启用多 dex 支持并重试构建

screenshot of a successful build after adding multidex

您还可以选择按照 Android 指南并修改项目的 Android 目录配置来手动支持多 dex。必须指定 多 dex 保留文件 以包含

io/flutter/embedding/engine/loader/FlutterLoader.class
io/flutter/util/PathUtils.class

此外,还包括应用启动中使用的任何其他类。有关手动添加多 dex 支持的更详细指南,请查看官方 Android 文档

查看应用清单

查看默认 应用清单 文件 AndroidManifest.xml。此文件位于 [project]/android/app/src/main 中。验证以下值

应用程序
application 标记中编辑 android:label 以反映应用程序的最终名称。
uses-permission
如果应用程序代码需要访问互联网,请添加 android.permission.INTERNET 权限。标准模板不包含此标记,但在开发期间允许访问互联网,以便在 Flutter 工具和正在运行的应用程序之间进行通信。

查看 Gradle 构建配置

查看默认 Gradle 构建文件 (build.gradle,位于 [project]/android/app),以验证值是否正确。

defaultConfig 块下

applicationId
指定最终的、唯一的 应用程序 ID
minSdkVersion
指定您设计应用程序运行的 最低 API 级别。默认为 flutter.minSdkVersion
targetSdkVersion
指定您设计应用程序运行的目标 API 级别。默认为 flutter.targetSdkVersion
versionCode
用作 内部版本号 的正整数。此数字仅用于确定一个版本是否比另一个版本更新,数字越大表示版本越新。此版本不会向用户显示。
versionName
用作向用户显示的版本号的字符串。此设置可以指定为原始字符串或对字符串资源的引用。
buildToolsVersion
Gradle 插件指定项目使用的构建工具的默认版本。你可以使用此选项指定不同版本的构建工具。

android 块下

compileSdkVersion
指定 Gradle 应使用哪个 API 级别来编译你的应用。默认为 flutter.compileSdkVersion

有关更多信息,请查看 Gradle 构建文件 中的模块级构建部分。

构建应用以供发布

在发布到 Play 商店时,你有两种可能的发布格式。

  • 应用包(首选)
  • APK

构建应用包

本部分介绍如何构建发布应用包。如果你已完成签名步骤,则会对应用包进行签名。此时,你可以考虑 混淆你的 Dart 代码,使其更难进行逆向工程。混淆你的代码涉及向构建命令添加几个标记,并维护其他文件以反混淆堆栈跟踪。

从命令行

  1. 输入 cd [project]
  2. 运行 flutter build appbundle
    (运行 flutter build 默认为发布构建。)

应用的发布包创建于 [project]/build/app/outputs/bundle/release/app.aab

默认情况下,应用包包含你的 Dart 代码和为 armeabi-v7a(ARM 32 位)、arm64-v8a(ARM 64 位)和 x86-64(x86 64 位)编译的 Flutter 运行时。

测试应用包

应用包可以通过多种方式进行测试。本部分介绍两种方式。

使用 bundletool 离线测试

  1. 如果你尚未这样做,请从 GitHub 存储库 下载 bundletool
  2. 从应用包生成一组 APK
  3. 将 APK 部署到已连接的设备

使用 Google Play 在线测试

  1. 将你的包上传到 Google Play 以进行测试。你可以在发布之前使用内部测试轨道或 alpha 或 beta 频道来测试包。
  2. 按照 这些步骤将你的包上传 到 Play 商店。

构建 APK

虽然应用包比 APK 更受欢迎,但仍有一些商店还不支持应用包。在这种情况下,请为每个目标 ABI(应用程序二进制接口)构建一个发布 APK。

如果您已完成签名步骤,则 APK 将被签名。此时,您可能考虑混淆您的 Dart 代码,以使其更难进行逆向工程。混淆您的代码涉及向您的构建命令添加几个标志。

从命令行

  1. 输入 cd [project]

  2. 运行 flutter build apk --split-per-abi。(flutter build 命令默认为 --release。)

此命令生成三个 APK 文件

  • [project]/build/app/outputs/apk/release/app-armeabi-v7a-release.apk
  • [project]/build/app/outputs/apk/release/app-arm64-v8a-release.apk
  • [project]/build/app/outputs/apk/release/app-x86_64-release.apk

删除 --split-per-abi 标志将生成一个 fat APK,其中包含为所有目标 ABI 编译的代码。此类 APK 的大小大于其拆分对应项,导致用户下载不适用于其设备架构的本机二进制文件。

在设备上安装 APK

按照以下步骤在连接的 Android 设备上安装 APK。

从命令行

  1. 使用 USB 数据线将您的 Android 设备连接到您的计算机。
  2. 输入 cd [project]
  3. 运行 flutter install

发布到 Google Play 商店

有关将您的应用发布到 Google Play 商店的详细说明,请查看Google Play 启动文档。

更新应用的版本号

应用的默认版本号为 1.0.0。要更新它,请导航到 pubspec.yaml 文件并更新以下行

version: 1.0.0+1

版本号是由点分隔的三位数字,例如上面的示例中的 1.0.0,后跟一个可选的构建号,例如上面的示例中的 1,用 + 分隔。

版本号和构建号都可以在 Flutter 的构建中通过分别指定 --build-name--build-number 来覆盖。

在 Android 中,build-name 用作 versionName,而 build-number 用作 versionCode。有关更多信息,请查看 Android 文档中的为您的应用设定版本

当您为 Android 重新构建应用时,pubspec 文件中版本号的任何更新都将更新 local.properties 文件中的 versionNameversionCode

Android 发布常见问题解答

以下是有关 Android 应用部署的一些常见问题。

我应该在何时构建应用包而不是 APK?

Google Play 商店建议您通过应用包而不是 APK 部署应用,因为这样可以更有效地向用户交付应用程序。但是,如果您通过 Play 商店以外的方式分发应用程序,那么 APK 可能是您的唯一选择。

什么是 Fat APK?

Fat APK 是一个包含嵌入其中的多个 ABI 二进制文件的单个 APK。这样做的好处是单个 APK 可以运行在多个架构上,因此具有更广泛的兼容性,但缺点是其文件大小要大得多,导致用户在安装应用程序时下载和存储更多字节。在构建 APK 而不是应用包时,强烈建议构建拆分 APK,如 构建 APK 中使用 --split-per-abi 标志所述。

支持的目标架构有哪些?

在发布模式下构建应用程序时,Flutter 应用可以编译为 armeabi-v7a(ARM 32 位)、arm64-v8a(ARM 64 位)和 x86-64(x86 64 位)。Flutter 支持通过 ARM 仿真构建 x86 Android。

我该如何对 flutter build appbundle 创建的应用包进行签名?

请参阅 对应用进行签名

我该如何在 Android Studio 中构建一个版本?

在 Android Studio 中,打开应用文件夹下的现有 android/ 文件夹。然后,在项目面板中选择build.gradle(模块:应用)

screenshot of gradle build script menu

接下来,选择构建变体。在主菜单中单击构建 > 选择构建变体。在构建变体面板中选择任何变体(调试是默认值)

screenshot of build variant menu

生成的应用包或 APK 文件位于应用文件夹内的 build/app/outputs 中。