构建和发布 Android 应用
- 添加启动器图标
- 启用 Material Components
- 签名应用
- 使用 R8 缩减代码
- 启用 Multidex 支持
- 查看应用清单
- 查看或更改 Gradle 构建配置
- 构建应用以供发布
- 发布到 Google Play 商店
- 更新应用的版本号
- Android 发布常见问题
要测试应用,您可以在命令行中使用 flutter run
,或者使用 IDE 中的“运行”和“调试”选项。
当您准备好准备应用的发布版本时,例如发布到Google Play 商店,此页面可以提供帮助。在发布之前,您可能需要对应用进行一些最后的润色。本指南说明如何执行以下任务
- 添加启动器图标
- 启用 Material Components
- 签署应用
- 使用 R8 缩减代码
- 启用 Multidex 支持
- 查看应用清单
- 查看构建配置
- 构建应用以供发布
- 发布到 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 应用签署。
要签署您的应用,请使用以下说明。
创建上传密钥库
#如果您有现有的密钥库,请跳到下一步。如果没有,请使用以下方法之一创建一个
在命令行中运行以下命令
在 macOS 或 Linux 上,使用以下命令
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \ -keysize 2048 -validity 10000 -alias upload
在 Windows 上,在 PowerShell 中使用以下命令
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks ` -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 ` -alias upload
此命令将
upload-keystore.jks
文件存储在您的主目录中。如果您想将其存储在其他位置,请更改传递给-keystore
参数的参数。**但是,请将keystore
文件保密;不要将其检入公共源代码控制!**
从应用引用密钥库
#创建一个名为 [project]/android/key.properties
的文件,其中包含对密钥库的引用。不要包含尖括号 (< >
)。它们表示文本用作您值的占位符。
storePassword=<password-from-previous-step>
keyPassword=<password-from-previous-step>
keyAlias=upload
storeFile=<keystore-file-location>
storeFile
可能位于 macOS 上的 /Users/<user name>/upload-keystore.jks
或 Windows 上的 C:\\Users\\<user name>\\upload-keystore.jks
。
在 Gradle 中配置签名
#在发布模式下构建应用时,配置 gradle 以使用您的上传密钥。要配置 gradle,请编辑 <project>/android/app/build.gradle
文件。
在
android
属性块之前定义并加载密钥库属性文件。将
keystoreProperties
对象设置为加载key.properties
文件。[project]/android/app/build.gradlekotlindef keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { ... }
在
android
属性块内的buildTypes
属性块之前添加签署配置。[project]/android/app/build.gradlekotlinandroid { // ... signingConfigs { release { keyAlias = keystoreProperties['keyAlias'] keyPassword = keystoreProperties['keyPassword'] storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword = keystoreProperties['storePassword'] } } 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 signingConfig = signingConfigs.release } } ... }
Flutter 现在签署所有发布版本。
要详细了解如何签署应用,请查看 developer.android.com 上的签署您的应用。
使用 R8 缩减代码
#R8 是 Google 的新代码压缩器。在构建发布版 APK 或 AAB 时,默认情况下启用它。要禁用 R8,请将 --no-shrink
标志传递给 flutter build apk
或 flutter build appbundle
。
启用 Multidex 支持
#在编写大型应用或使用大型插件时,在将目标 API 设置为 20 或以下时,您可能会遇到 Android 的 64k 方法限制。在使用未启用压缩的 flutter run
运行应用的调试版本时,也可能会遇到这种情况。
Flutter 工具支持轻松启用 Multidex。最简单的方法是在系统提示时选择加入 Multidex 支持。该工具检测 Multidex 构建错误并在进行更改之前询问您的 Android 项目。选择加入允许 Flutter 自动依赖于 androidx.multidex:multidex
并使用生成的 FlutterMultiDexApplication
作为项目的应用程序。
当您尝试使用 IDE 中的“运行”和“调试”选项构建和运行应用时,您的构建可能会失败并显示以下消息
要从命令行启用 Multidex,请运行 flutter run --debug
并选择 Android 设备
出现提示时,输入 y
。Flutter 工具启用 Multidex 支持并重试构建
您也可以选择通过遵循 Android 的指南和修改项目的 Android 目录配置来手动支持 Multidex。必须指定Multidex 保留文件以包含
io/flutter/embedding/engine/loader/FlutterLoader.class
io/flutter/util/PathUtils.class
此外,还包括应用启动中使用的任何其他类。有关手动添加 Multidex 支持的更详细指南,请查看官方Android 文档。
查看应用清单
#查看默认的应用清单文件。
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="[project]"
...
</application>
...
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
验证以下值
标签 | 属性 | 值 |
---|---|---|
application | 编辑application 标签中的 android:label 以反映应用的最终名称。 | |
uses-permission | 如果您的应用需要 Internet 访问,请将 android.permission.INTERNET 权限值添加到 android:name 属性中。标准模板不包含此标签,但在开发过程中允许 Internet 访问以启用 Flutter 工具和正在运行的应用之间的通信。 |
查看或更改 Gradle 构建配置
#要验证 Android 构建配置,请查看默认Gradle 构建脚本中的 android
块。默认的 Gradle 构建脚本位于 [project]/android/app/build.gradle
中。您可以更改任何这些属性的值。
android {
namespace = "com.example.[project]"
// Any value starting with "flutter." gets its value from
// the Flutter Gradle plugin.
// To change from these defaults, make your changes in this file.
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
...
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com.cn/studio/build/application-id.html).
applicationId = "com.example.[project]"
// You can update the following values to match your application needs.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
// These two properties use values defined elsewhere in this file.
// You can set these values in the property declaration
// or use a variable.
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
}
buildTypes {
...
}
}
需要在 build.gradle 中调整的属性
#属性 | 用途 | 默认值 |
---|---|---|
compileSdk | 编译应用所依据的 Android API 级别。这应该是可用的最高版本。如果您将此属性设置为 31 ,则可以在运行 API 30 或更低版本的设备上运行您的应用,只要您的应用不使用特定于 31 的任何 API 即可。 | |
defaultConfig | ||
.applicationId | 标识您的应用的最终唯一应用 ID。 | |
.minSdk | 您设计应用以运行的最低 Android API 级别。 | flutter.minSdkVersion |
.targetSdk | 您测试应用以运行的 Android API 级别。您的应用应该在所有 Android API 级别上运行,直到此级别。 | flutter.targetSdkVersion |
.versionCode | 一个正整数,用于设置内部版本号。此数字仅确定哪个版本比另一个版本更新。较大的数字表示较新的版本。应用用户永远不会看到此值。 | |
.versionName | 您的应用显示为其版本号的字符串。将此属性设置为原始字符串或对字符串资源的引用。 | |
.buildToolsVersion | Gradle 插件指定项目使用的 Android 构建工具的默认版本。要指定不同版本的构建工具,请更改此值。 |
要了解有关 Gradle 的更多信息,请查看 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
标志将生成一个包含为所有目标 ABI 编译的代码的完整 APK。此类 APK 的大小大于其拆分后的对应文件,导致用户下载与其设备架构不相关的原生二进制文件。
在设备上安装 APK
#按照以下步骤将 APK 安装到已连接的 Android 设备上。
从命令行
- 使用 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 可能是您的唯一选择。
什么是胖 APK?
#一个 完整 APK 是一个包含多个 ABI 的二进制文件的单个 APK。这样做的好处是单个 APK 可以运行在多种架构上,从而具有更广泛的兼容性,但缺点是其文件大小更大,导致用户在安装应用程序时下载和存储更多字节。在构建 APK 而不是应用包时,强烈建议构建拆分 APK,如 构建 APK 中使用 --split-per-abi
标志所述。
支持哪些目标架构?
#在发布模式下构建应用程序时,Flutter 应用可以编译为 armeabi-v7a(ARM 32 位)、arm64-v8a(ARM 64 位)和 x86-64(x86 64 位)。
如何签名 flutter build appbundle
创建的应用包?
#请参阅 签名应用。
如何在 Android Studio 中构建发布版本?
#在 Android Studio 中,打开应用文件夹下的现有 android/
文件夹。然后,在项目面板中选择build.gradle (Module: app)
接下来,选择构建变体。单击主菜单中的构建 > 选择构建变体。在构建变体面板中选择任何变体(调试是默认值)
生成的应用包或 APK 文件位于应用文件夹内的 build/app/outputs
中。
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024-08-20。 查看源代码 或 报告问题。