构建并发布 Android 应用
在典型的开发周期中,你可以使用命令行中的 flutter run
或使用 IDE 中的运行和调试选项来测试应用。默认情况下,Flutter 会构建应用的调试版本。
当你准备为应用准备发布版本时,例如要发布到 Google Play 商店,此页面可以提供帮助。在发布之前,你可能希望对应用进行一些润色。此页面涵盖以下主题
- 添加启动器图标
- 启用 Material 组件
- 对应用进行签名
- 使用 R8 压缩代码
- 启用多 dex 支持
- 查看应用清单
- 查看构建配置
- 为发布构建应用
- 发布到 Google Play 商店
- 更新应用版本号
- Android 发布常见问题解答
添加启动器图标
当创建新的 Flutter 应用时,它有一个默认启动器图标。要自定义此图标,你可能希望查看 flutter_launcher_icons 包。
或者,你可以使用以下步骤手动进行
-
查看 Material Design 产品图标 指南以了解图标设计。
-
在
[project]/android/app/src/main/res/
目录中,将图标文件放置在使用 配置限定符命名的文件夹中。默认的mipmap-
文件夹演示了正确的命名约定。 -
在
AndroidManifest.xml
中,更新application
标记的android:icon
属性,以引用上一步中的图标(例如,<application android:icon="@mipmap/ic_launcher" ...
)。 -
要验证是否已替换图标,请运行应用并检查启动器中的应用图标。
启用 Material Components
如果你的应用使用 平台视图,你可能希望按照 Android 入门指南 中所述的步骤启用 Material Components。
例如
- 在
<my-app>/android/app/build.gradle
中添加对 Android Material 的依赖
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
// ...
}
要了解最新版本,请访问 Google Maven。
- 在
<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">
- 在
<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 应用签名。
要签名您的应用,请使用以下说明。
创建上传密钥库
如果您有现有密钥库,请跳至下一步。如果没有,请使用以下方法之一创建一个
- 按照 Android Studio 密钥生成步骤 进行操作
-
在命令行中运行以下命令
在 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 在发布模式下构建应用时使用上传密钥。
-
在
android
块之前添加属性文件中的密钥库信息def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { ... }
将
key.properties
文件加载到keystoreProperties
对象中。 -
找到
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 apk
或 flutter build appbundle
。
启用多 dex 支持
在编写大型应用或使用大型插件时,如果针对的最低 API 为 20 或更低,则可能会遇到 Android 64k 方法的 dex 限制。在使用未启用精简的 flutter run
运行应用的调试版本时,也可能会遇到这种情况。
Flutter 工具支持轻松启用多 dex。最简单的方法是在提示时选择加入多 dex 支持。该工具会检测到多 dex 构建错误,并在对 Android 项目进行更改之前询问。选择加入后,Flutter 可以自动依赖 androidx.multidex:multidex
,并使用生成的 FlutterMultiDexApplication
作为项目的应用程序。
当您尝试使用 IDE 中的运行和调试选项构建并运行应用时,您的构建可能会失败,并显示以下消息
要从命令行启用多 dex,请运行 flutter run --debug
并选择一个 Android 设备
在提示时,输入 y
。Flutter 工具会启用多 dex 支持并重试构建
您还可以选择按照 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 代码,使其更难进行逆向工程。混淆你的代码涉及向构建命令添加几个标记,并维护其他文件以反混淆堆栈跟踪。
从命令行
- 输入
cd [project]
- 运行
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 离线测试
- 如果你尚未这样做,请从 GitHub 存储库 下载
bundletool
。 - 从应用包生成一组 APK。
- 将 APK 部署到已连接的设备。
使用 Google Play 在线测试
- 将你的包上传到 Google Play 以进行测试。你可以在发布之前使用内部测试轨道或 alpha 或 beta 频道来测试包。
- 按照 这些步骤将你的包上传 到 Play 商店。
构建 APK
虽然应用包比 APK 更受欢迎,但仍有一些商店还不支持应用包。在这种情况下,请为每个目标 ABI(应用程序二进制接口)构建一个发布 APK。
如果您已完成签名步骤,则 APK 将被签名。此时,您可能考虑混淆您的 Dart 代码,以使其更难进行逆向工程。混淆您的代码涉及向您的构建命令添加几个标志。
从命令行
-
输入
cd [project]
。 -
运行
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。
从命令行
- 使用 USB 数据线将您的 Android 设备连接到您的计算机。
- 输入
cd [project]
。 - 运行
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
文件中的 versionName
和 versionCode
。
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(模块:应用)
接下来,选择构建变体。在主菜单中单击构建 > 选择构建变体。在构建变体面板中选择任何变体(调试是默认值)
生成的应用包或 APK 文件位于应用文件夹内的 build/app/outputs
中。