Skip to content

打包 Android 应用 (Packaging app for Android) ​


本指南介绍了将 Flet 应用打包为 Android APK 和 Android App Bundle (AAB) 的详细步骤。

提示

本指南提供了专门针对 Android 平台的详细信息。更通用和互补的打包信息,请参阅发布 Flet 应用。

前提条件 (Prerequisites) ​

Android SDK ​

构建过程需要安装 Java (JDK 17) 和 Android SDK。

如果在第一次运行 flet build 命令时,系统缺少这两个组件或检测到不兼容的版本,所需工具将会被自动下载并安装。

  • JDK 将被安装在 $HOME/java/<version>(例如:17.0.13+11)。
  • 如果已安装 Android Studio,Flet CLI 将直接使用其自带的 SDK:
    • macOS: ~/Library/Android/sdk
    • Windows: %LOCALAPPDATA%\Android\Sdk
    • Linux: ~/Android/Sdk
  • 否,一个独立的 Android SDK 将被安装在:
    • macOS/Linux: ~/Android/sdk
    • Windows: %USERPROFILE%\Android\sdk

此外,如果设置了 ANDROID_HOME 和 ANDROID_SDK_ROOT 环境变量,构建程序也会予以遵循。

适用于 Android 的 Python 二进制轮子包 (wheels) ​

二进制 Python 包(与仅用 Python 编写的“纯” Python 包不同)是部分使用 C、Rust 或其他语言编写的,会生成原生平台代码的包(例如 numpy、cryptography 或 pydantic-core)。

请确保你的 Flet 应用中所使用的所有非纯(二进制)依赖包,都具有预编译的适用于 Android 的 wheel 分发包。


flet build apk ​

提示

此命令可以在 macOS、Linux 或 Windows 上运行。

构建发布版(Release)的 Android APK 文件。

发布版构建针对生产环境进行了深度优化,这意味着它们不支持调试,旨在发布到 Google Play 等应用商店中。

为了部署到 Google Play 应用商店,推荐:

  • 使用 Android App Bundle (AAB) 以获得更高效的分发体验和更小的安装体积。
  • 或者按 ABI(CPU 架构)拆分 APK 以减小单个 APK 的体积。
按 ABI 拆分 APK (Split APK per ABI) ​

Android 设备使用不同的 CPU 架构,因此 APK 可以针对不同的应用二进制接口(ABI)进行优化。

默认情况下,Flet 会构建一个包含所有支持 ABI 的原生二进制文件的“胖”(fat)APK。这最大化了设备兼容性,但会增加 APK 的体积。

启用 ABI 拆分后,将为每个 ABI 生成一个对应的 APK。这能减小文件体积,但需要你为不同设备分发正确的 APK。

支持的目标架构 ​
  • arm64-v8a
  • armeabi-v7a
  • x86_64
  • x86

解析优先级

  1. --split-per-abi
  2. [tool.flet.android].split_per_abi
  3. 默认值为 false

启用时,默认会生成 3 个 APK,分别对应以下 ABI:arm64-v8a、armeabi-v7a 和 x86_64。这些可以通过设置目标架构进行自定义。

示例 命令行构建或 pyproject.toml 配置:

bash
flet build apk --split-per-abi

flet build aab ​

提示

此命令可以在 macOS、Linux 或 Windows 上运行。

构建发布版(Release)的 Android App Bundle (AAB) 文件。

发布版构建针对生产环境进行了深度优化,不支持调试,旨在发布到 Google Play 商店中。

由于 AAB 格式在应用体积上进行了深度优化,因此强烈建议在发布到 Google Play 商店时使用 AAB 格式(而不是 APK)。

如果你需要限制包含在 AAB 包中的 ABI,请在 split_per_abi 为 false 的情况下使用 --arch 或 [tool.flet.android].target_arch 参数。


对 Android 包进行签名 (Signing an Android bundle) ​

Android 要求所有 APK 在安装到设备或进行更新之前,必须使用数字证书进行数字签名。使用 Android App Bundle 进行发布时,你需要在将应用包上传到 Play Console 之前使用上传密钥对其进行签名,随后 Google Play 应用签名(Play App Signing)会处理剩下的事情。对于在 Play 商店或其他应用商店使用 APK 分发的应用,你必须手动为上传的 APK 进行签名。

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

Android 使用两种签名密钥:上传密钥(upload key)和应用签名密钥(app signing key)。

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

要创建你的应用签名密钥,请按照 Google Play 官方文档中所述使用 Play App Signing。

请按照以下说明对你的应用进行签名。

注意

如果不提供上传密钥库(keystore),发布版构建将默认使用调试密钥(debug key)进行签名。这对于本地测试是可以的,但无法上传到 Play 商店中。

创建上传密钥库 (Create an upload keystore) ​

如果你已有现成的密钥库,请跳过此步骤。如果没有,请使用以下方法之一创建一个:

  • 按照 Android Studio 密钥生成步骤操作。

  • 或者在命令行终端中运行以下命令:

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

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

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

    powershell
    keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks `
        -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 `
        -alias upload

系统会提示你输入几项详细信息,如密钥库密码、密钥别名、你的名字和位置。请记住密码和别名,以便在下面的配置步骤中使用。

你的用户主目录下将生成一个名为 upload-keystore.jks 的文件。如果你想将其存储在其他地方,请更改传递给 -keystore 参数的路径。

提示

keytool 命令可能不在系统 PATH 路径中 —— 它是 Java 的一部分,而 Java 是作为 Android Studio 的一部分安装的。要找到具体的路径,请运行 flutter doctor -v 并找到“Java binary at:”之后打印的路径。然后使用该全路径,将(末尾的)java 替换为 keytool。如果你的路径中包含带空格的名称(如 Program Files),请对该名称使用适合你平台的书写方式(例如在 Windows 上使用 "Program Files",在 macOS/Linux 上使用 Program\ Files)。

-storetype JKS 标签仅对 Java 9 或更新版本是必需的。从 Java 9 版本开始,密钥库类型默认已改为 PKCS12。

重要安全警告

切勿将你的密钥库文件公开或提交到公共源码控制仓库(如 GitHub)中!

别名 (Key alias) ​

密钥库中对应密钥的别名。

解析优先级

  1. --android-signing-key-alias
  2. FLET_ANDROID_SIGNING_KEY_ALIAS 环境变量
  3. [tool.flet.android.signing].key_alias
  4. 默认值为 "upload"

示例 命令行构建或 pyproject.toml 配置:

bash
flet build aab --android-signing-key-alias upload
密钥库路径 (Key store) ​

指向密钥库文件(.jks 扩展名)的路径。

如果你原样使用了上面的命令行创建命令,在 macOS 上该文件可能位于 /Users/<用户名>/upload-keystore.jks,在 Windows 上位于 C:\Users\<用户名>\upload-keystore.jks。

解析优先级

  1. --android-signing-key-store
  2. [tool.flet.android.signing].key_store
  3. FLET_ANDROID_SIGNING_KEY_STORE 环境变量

示例 命令行构建或 pyproject.toml 配置:

bash
flet build aab --android-signing-key-store path/to/store.jks
密钥库密码 (Key store password) ​

解锁密钥库文件的密码。

解析优先级

  1. --android-signing-key-store-password
  2. FLET_ANDROID_SIGNING_KEY_STORE_PASSWORD 环境变量
  3. 密钥密码(key password)

示例 命令行构建或 pyproject.toml 配置:

bash
flet build aab --android-signing-key-store-password password123
密钥密码 (Key password) ​

用于访问密钥库内部私钥的密码。

解析优先级

  1. --android-signing-key-password
  2. FLET_ANDROID_SIGNING_KEY_PASSWORD 环境变量
  3. 密钥库密码(key store password)

示例 命令行构建或 pyproject.toml 配置:

bash
flet build aab --android-signing-key-password password123

Android 清单文件 (Android Manifest) ​

Android 清单文件向 Android 构建工具、Android 操作系统和 Google Play 描述了应用的基本信息。这些信息将被自动写入到 AndroidManifest.xml 文件中。

应用程序属性 (Application attributes) ​

你可以在构建模板的 AndroidManifest.xml 文件的 <application> 元素中添加或覆盖属性。

解析优先级

  1. [tool.flet.android.manifest_application]

示例pyproject.toml 中的写法:

toml
[tool.flet.android.manifest_application]
usesCleartextTraffic = "true"
allowBackup = "false"
元数据 (Meta-data) ​

为父组件提供的附加、任意数据的键值对。

一个元数据项由以下部分组成:

  • name: 唯一名称,通常采用 Java 风格的命名约定(例如 "com.sample.project.activity.fred")。
  • value: 元数据的值。Android 支持字符串、整数、布尔值和浮点数。Flet 会将这些值统一作为字符串写入,因此请传入你希望 Android 读取的字面量(例如 "true"、"123"、"1.23")。

解析优先级

  1. --android-meta-data
  2. [tool.flet.android.meta_data]

示例 命令行构建或 pyproject.toml 配置:

bash
flet build apk \
  --android-meta-data firebase_analytics_collection_enabled=true \
  --android-meta-data default_timeout_seconds=30
功能特征 (Features) ​

应用所使用硬件或软件功能特征。

  • name: 以描述性字符串指定应用程序使用的单一硬件或软件功能特征。属性值区分大小写。
  • required: 布尔值(true 或 false),指示应用程序是否必须要求 name 指定的功能特征。

解析优先级

  1. --android-features
  2. [tool.flet.android.feature]
  3. 跨平台权限包所注入的值(如有)。
  4. 默认值:android.software.leanback=false, android.hardware.touchscreen=false

支持的传参形式 接受重复的 <name>=<required> 键值对。<required> 值可以是 true 或 false(不区分大小写)。

示例 命令行构建或 pyproject.toml 配置:

bash
flet build apk \
  --android-features android.hardware.camera=true \
  --android-features android.hardware.location.gps=false
权限 (Permissions) ​

尽可能使用跨平台权限,并在下面添加特定于 Android 的权限。

解析优先级

  1. --android-permissions
  2. [tool.flet.android.permission]
  3. 跨平台权限包所注入的值(如有)。
  4. 默认值:android.permission.INTERNET=true

支持的传参形式 接受重复的 <name>=<enabled> 键值对。<enabled> 值可以是 true 或 false(不区分大小写)。值为 false 的权限不会被包含在生成的清单文件中。

示例 命令行构建或 pyproject.toml 配置:

bash
flet build apk \
  --android-permissions android.permission.READ_EXTERNAL_STORAGE=true \
  --android-permissions android.permission.WRITE_EXTERNAL_STORAGE=true
最低 SDK 版本 (Minimum SDK version) ​

应用可以安装的最低 Android API 级别。

解析优先级

  1. [tool.flet.android].min_sdk_version
  2. Flutter 默认值:flutter.minSdkVersion

示例pyproject.toml 中的写法:

toml
[tool.flet.android]
min_sdk_version = 24
目标 SDK 版本 (Target SDK version) ​

应用针对运行行为和兼容性优化的目标 Android API 级别。

解析优先级

  1. [tool.flet.android].target_sdk_version
  2. Flutter 默认值:flutter.targetSdkVersion

示例pyproject.toml 中的写法:

toml
[tool.flet.android]
target_sdk_version = 35
自适应图标背景色 (Adaptive icon background) ​

Android 自适应启动器图标所使用的背景颜色。

该值会在为 Android 生成应用图标时被自动应用。

解析优先级

  1. --android-adaptive-icon-background
  2. [tool.flet.android].adaptive_icon_background
  3. 默认值:#ffffff

示例 命令行构建或 pyproject.toml 配置:

bash
flet build apk --android-adaptive-icon-background "#0B6BFF"

ADB 调试建议 (ADB Tips) ​

Android 调试桥 (adb) 是一个包含在 Android SDK 中的命令行工具,允许你与 Android 设备和模拟器进行通信。

如果你在 macOS 上安装了 Android Studio,adb 通常位于:~/Library/Android/sdk/platform-tools/adb。

在模拟器或真实设备内部运行交互式命令 ​
bash
adb shell
在交互式 Android shell 中浏览文件系统时遇到“权限拒绝”(permission denied)错误 ​
bash
su
从 Android 设备下载文件到你的本地电脑 ​
bash
adb pull <设备路径> <本地路径>
在 Android 设备上安装 APK 应用程序 ​
bash
adb install <你的_apk_路径.apk>

这对于实体物理设备和模拟器均适用。如果连接了多个设备,请指定目标设备:

bash
adb -s <设备名> install <你的_apk_路径.apk>

你可以通过以下命令列出所有可用设备:

bash
adb devices

关注我,学习大模型、大数据、Python等热门技术。