跳到主要内容

将 Flet 应用发布到多个平台

简介

Flet CLI 提供了 flet build 命令,该命令允许将 Flet 应用打包为独立的可执行文件或安装包以便分发。

平台矩阵

以下矩阵显示了您应该在哪个操作系统上运行 flet build 命令,以便为特定平台构建包:

运行于 / flet buildapk/aabipamacoslinuxwindowsweb
macOS
Windows✅ (WSL)
Linux

先决条件

Flutter SDK

必须安装 Flutter SDK 3.24 或更高版本,并且 flutterdart 命令的路径必须添加到 PATH 环境变量中。

请根据您的平台遵循官方的Flutter 安装指南

请注意每个平台上 Flutter 自身的要求,例如 macOS 上的 XCode 和 Cocopods,Windows 上的 Visual Studio 2022 或 Linux 上的其他工具和库。

项目结构

flet build 命令假定 Flet 项目具有以下最小结构。

/assets/
icon.png
main.py
pyproject.toml
requirements.txt

main.py 是您的 Flet 应用的入口点,末尾带有 ft.app(main)。可以使用 --module-name 参数指定不同的入口点。

assets 是一个可选目录,其中包含应用资产(您的应用所需的图像、声音、文本和其他文件)以及用于包图标和启动屏幕的图像。

如果仅提供 icon.png(或其他支持的格式,如 .bmp.jpg.webp),它将被用作源图像来为所有平台生成所有图标和启动屏幕。有关图标和启动屏幕的更多信息,请参见下面的部分。

pyproject.toml 包含应用程序的元数据,列出其依赖项并控制构建过程。

requirements.txt 也可用于列出应用程序的需求。不过这是可选的,如果同时存在 pyproject.tomlrequirements.txt,则后者将被忽略。

项目依赖项列表中至少应包含 flet 包。

::: 注意 不要使用 pip freeze 不要使用 pip freeze > requirements.txt 命令为将在移动设备上运行的应用创建 requirements.txt。因为当您在桌面运行 pip freeze 命令时,requirements.txt 中将包含不打算在移动设备上运行的依赖项,例如 watchdog

手动选择 requirements.txt,使其仅包含您的应用所需的直接依赖项以及 flet。 :::

以正确的项目结构开始的最简单方法是使用 flet create 命令:

flet create myapp

其中 myapp 是目标目录。

flet create 应用模板将 main.pyassets 放入 src 目录中,该目录的路径由 pyproject.toml 中的 tool.flet.app.path 设置控制:

[tool.flet.app]
path = "src"

工作原理

flet build <目标平台> 命令可以从 Flet 应用目录的根目录运行:

<flet_app_directory> % flet build <目标平台>

其中 <目标平台> 可以是以下之一:apkaabipawebmacoswindowslinux

当从不同的目录运行时,您可以提供 Flet 应用所在目录的路径:

flet build <目标平台> <python_app 目录路径>

构建结果将被复制到 <python_app_directory>/build/<目标平台>。您可以使用 --output 选项指定自定义输出目录:

flet build <目标平台> --output <输出目录路径>

flet build 使用 Flutter SDK 和多个 Flutter 包从您的 Flet 应用构建分发包。

当您运行 flet build <目标平台> 命令时,它会:

  • https://github.com/flet-dev/flet-build-template 模板在 {flet_app_directory}/build/flutter 目录中创建一个新的 Flutter 项目。Flutter 应用将在资产中包含一个打包的 Python 应用,并使用 fletserious_python 包分别运行 Python 应用并渲染其 UI。该项目是临时的,完成后将被删除。
  • 将自定义图标和启动图像(见下文)从 assets 目录复制到 Flutter 项目中。
  • 使用 flutter_launcher_icons 包为所有平台生成图标。
  • 使用 flutter_native_splash 包为 Web、iOS 和 Android 目标生成启动屏幕。
  • 使用 serious_python 包的 package 命令打包 Python 应用。package 命令从 https://pypi.orghttps://pypi.flet.dev 为所选平台安装纯 Python 包和二进制 Python 包。如果进行了配置,已安装包和/或应用程序的 .py 文件将被编译为 .pyc 文件。除 build 目录外的所有文件都将添加到包资产中。
  • 运行 flutter build <目标平台> 命令以生成可执行文件或安装包。
  • 将构建结果复制到 {flet_app_directory}/build/<目标平台> 目录。

包含可选控件

如果您的应用使用以下控件,则必须将其包添加到构建命令中:

  • flet_ads 包中实现的广告控件(BannerAdInterstitialAd)。
  • Audio 控件,在 flet_audio 包中实现。
  • AudioRecorder 控件,在 flet_audio_recorder 包中实现。
  • Flashlight 控件,在 flet_flashlight 包中实现。
  • Geolocator 控件,在 flet_geolocator 包中实现。
  • Lottie 控件,在 flet_lottie 包中实现。
  • Map 控件,在 flet_map 包中实现。
  • PermissionHandler 控件,在 flet_permission_handler 包中实现。
  • Rive 控件,在 flet_rive 包中实现。
  • Video 控件,在 flet_video 包中实现。
  • WebView 控件,在 flet_webview 包中实现。

使用 --include-packages <包_1> <包_2>... 选项添加带有可选 Flet 控件的 Flutter 包,或在 pyproject.toml 中使用 tool.flet.flutter.dependencies 部分。

例如,要使用 VideoAudio 控件构建您的 Flet 应用,请在 flet build 命令中添加 --include-packages flet_video flet_audio

flet build apk --include-packages flet_video flet_audio

或者在 pyproject.toml 中进行相同的设置:

flutter.dependencies = ["flet_video", "flet_audio"]

或者使用带有版本的替代语法:

[tool.flet.flutter.dependencies]
flet_video = "1.0.0"
flet_audio = "2.0.0"

或者使用您磁盘上包的路径:

[tool.flet.flutter.dependencies.my_package]
path = "/path/to/my_package"

图标

您可以使用 Flet 应用的 assets 目录中的图像为所有平台(除 Linux 外)自定义应用图标。

如果仅提供 icon.png(或其他支持的格式,如 .bmp.jpg.webp),它将被用作生成所有图标的源图像。

  • iOS - icon_ios.png(或任何支持的图像格式)。建议的最小图像大小为 1024 像素。图像不应是透明的(具有 alpha 通道)。默认为自动去除 alpha 通道的 icon.png
  • Android - icon_android.png(或任何支持的图像格式)。建议的最小图像大小为 192 像素。默认为 icon.png
  • Web - icon_web.png(或任何支持的图像格式)。建议的最小图像大小为 512 像素。默认为 icon.png
  • Windows - icon_windows.png(或任何支持的图像格式)。将生成 256 像素大小的 ICO。默认为 icon.png。如果提供了 icon_windows.ico 文件,它将直接复制到 windows/runner/resources/app_icon.ico 而不进行修改。
  • macOS - icon_macos.png(或任何支持的图像格式)。建议的最小图像大小为 1024 像素。默认为 icon.png

启动屏幕

您可以使用 Flet 应用的 assets 目录中的图像为 iOS、Android 和 Web 应用自定义启动屏幕。

如果仅提供 splash.pngicon.png(或其他支持的格式,如 .bmp.jpg.webp),它将被用作生成所有启动屏幕的源图像。

  • iOS(亮色) - splash_ios.png(或任何支持的图像格式)。默认为 splash.png,然后是 icon.png
  • iOS(暗色) - splash_dark_ios.png(或任何支持的图像格式)。默认为亮色 iOS 启动屏幕,然后是 splash_dark.png,然后是 splash.png,然后是 icon.png
  • Android(亮色) - splash_android.png(或任何支持的图像格式)。默认为 splash.png,然后是 icon.png
  • Android(暗色) - splash_dark_android.png(或任何支持的图像格式)。默认为亮色 Android 启动屏幕,然后是 splash_dark.png,然后是 splash.png,然后是 icon.png
  • Web(亮色) - splash_web.png(或任何支持的图像格式)。默认为 splash.png,然后是 icon.png
  • Web(暗色) - splash_dark_web.png(或任何支持的图像格式)。默认为亮色 Web 启动屏幕,然后是 splash_dark.png,然后是 splash.png,然后是 icon.png

--splash-color 选项指定亮色模式下启动屏幕的背景颜色。默认为 #ffffff

--splash-dark-color 选项指定暗色模式下启动屏幕的背景颜色。默认为 #333333

pyproject.toml 中配置启动屏幕设置:

[tool.flet.splash]
color = "#FFFF00" # --splash-color
dark_color = "#8B8000" # --splash-dark-color
web = false # --no-web-splash
ios = false # --no-ios-splash
android = false # --no-android-splash

入口点

默认情况下,flet build 命令假定 main.py 是您的 Flet 应用的入口点,即末尾带有 ft.app(main) 的文件。可以使用 --module-name 参数或在 pyproject.toml 中指定不同的入口点:

[tool.flet]
app.module = "main"

编译和清理

默认情况下,flet build 命令不会将应用程序的 .py 文件编译为 .pyc 文件,这使您可以避免(或推迟?)在应用程序中发现任何语法错误,并成功完成打包。

您可以使用以下新选项启用编译和清理:

  • --compile-app - 编译应用程序的 .py 文件。
  • --compile-packages - 编译已安装包的 .py 文件。
  • --cleanup-on-compile - 在编译成功后删除不必要的文件。

pyproject.toml 中配置编译:

[tool.flet]
compile.app = true # --compile-app
compile.packages = true # --compile-packages
compile.cleanup = true # --cleanup-on-compile

权限

flet build 命令允许对嵌入到 AndroidManifest.xmlInfo.plist.entitlements 文件中的权限、功能和授权进行精细控制。

有关设置特定 iOSAndroidmacOS 权限的信息,请参阅平台指南。

跨平台权限

有预定义的权限,它们分别映射到各个平台的 Info.plist*.entitlementsAndroidManifest.xml

设置跨平台权限:

flet build --permissions permission_1 permission_2...

支持的权限:

  • location
  • camera
  • microphone
  • photo_library

iOS 到 Info.plist 条目的映射

  • location
    • NSLocationWhenInUseUsageDescription = 此应用在使用时使用位置服务。
    • NSLocationAlwaysAndWhenInUseUsageDescription = 此应用使用位置服务。
  • camera
    • NSCameraUsageDescription = 此应用使用相机拍摄照片和视频。
  • microphone
    • NSMicrophoneUsageDescription = 此应用使用麦克风录制声音。
  • photo_library
    • NSPhotoLibraryUsageDescription = 此应用将照片和视频保存到照片库。

macOS 到授权的映射

  • location
    • com.apple.security.personal-information.location = True
  • camera
    • com.apple.security.device.camera = True
  • microphone
    • com.apple.security.device.audio-input = True
  • photo_library
    • com.apple.security.personal-information.photos-library = True

Android 映射

  • location
    • 权限:
      • android.permission.ACCESS_FINE_LOCATION": True
      • android.permission.ACCESS_COARSE_LOCATION": True
      • android.permission.ACCESS_BACKGROUND_LOCATION": True
    • 功能:
      • android.hardware.location.network": False
      • android.hardware.location.gps": False
  • camera
    • 权限:
      • android.permission.CAMERA": True
    • 功能:
      • android.hardware.camera": False
      • android.hardware.camera.any": False
      • android.hardware.camera.front": False
      • android.hardware.camera.external": False
      • android.hardware.camera.autofocus": False
  • microphone
    • 权限:
      • android.permission.RECORD_AUDIO": True
      • android.permission.WRITE_EXTERNAL_STORAGE": True
      • android.permission.READ_EXTERNAL_STORAGE": True
  • photo_library
    • 权限:
      • android.permission.READ_MEDIA_VISUAL_USER_SELECTED": True

pyproject.toml 中配置跨平台权限:

[tool.flet]
permissions = ["camera", "microphone"]

版本控制

您可以使用 --build-number--build-version 参数为构建的可执行文件或包提供版本信息。这是用于在 App Store 和 Google Play 中区分一个构建/发布与另一个构建/发布的信息,并在关于对话框中向用户显示。

--build-number - 一个整数(默认为 1),用作内部版本号的标识符。每个构建必须具有唯一的标识符,以将其与以前的构建区分开来。它用于确定一个构建是否比另一个构建更新,数字越高表示构建越新。

--build-version - 一个 "x.y.z" 字符串(默认为 1.0.0),用作向用户显示的版本号。对于您的应用的每个新版本,您将提供一个版本号以将其与以前的版本区分开来。

pyproject.toml 中配置显示版本和版本