Flutter多平台打包发布
Flutter多平台打包发布 Android ios Windows macos web linux
本文档将详细讲解如何使用 Flutter 和工具打包发布多平台应用,包括 Android、iOS、Windows、macOS、Web 和 Linux。并通过 flutter_distributor 工具来实现高级打包功能。
准备工作
- 安装 Flutter SDK - 下载并安装 Flutter SDK:Flutter 官网 
- 配置环境变量: - export PATH="$PATH:/path-to-flutter/bin"
 
- 检查环境配置 - flutter doctor
- 安装 - flutter_distributor工具- 安装 flutter_distributor - dart pub global activate flutter_distributor
 
- 项目初始化 - 创建一个新的 Flutter 项目或打开现有项目: - flutter create my_app cd my_app
 
Android 打包
- 使用 Flutter 命令打包 APK - 打包 APK 文件并分离 ABI: - flutter build apk --release --split-per-abi
- 输出的打包文件位于 - build/app/outputs/flutter-apk/。
 
- 发布 AAB 文件 - 如果需要发布 AAB 文件到 Google Play: - flutter build appbundle --release
 
iOS 打包
- 打包 iOS 应用 - 不签名的 Release 构建: - flutter build ios --release --no-codesign
 
- 生成 IPA 文件 - 进入构建输出目录: - cd build/ios/iphoneos/
- 创建 Payload 文件夹并移动应用: - mkdir Payload cp -r Runner.app Payload/
- 打包成 IPA 文件: - zip -r Runner.ipa Payload
 
Web 打包
- 打包 Web 应用 - flutter build web --release
- 打包结果 - 构建输出位于 build/web目录中。
- 可以将其部署到任何支持静态文件托管的服务(如 Nginx、Firebase Hosting)。
 
- 构建输出位于 
Windows 打包
- 打包 Windows 应用 - 使用 Flutter 构建: - flutter build windows
- 构建结果位于 - build/windows/runner/Release目录。
 
- 高级打包工具 - 使用 flutter_distributor打包为 EXE 或 MSIX(详细见 高级功能)。
 
- 使用 
macOS 打包
- 打包 macOS 应用 - flutter build macos
- 构建输出 - 构建结果位于 build/macos/Build/Products/Release目录。
 
- 构建结果位于 
- 高级打包工具 - 使用 flutter_distributor打包为 DMG(详细见 高级功能)。
 
- 使用 
Linux 打包
- 打包 Linux 应用 - flutter build linux
- 构建输出 - 构建结果位于 build/linux/x64/release/bundle目录。
 
- 构建结果位于 
- 高级打包工具 - 使用 flutter_distributor打包为 DEB、RPM 或 AppImage(详细见 高级功能)。
 
- 使用 
 高级功能:flutter_distributor
flutter_distributor 是一个强大的工具,支持跨平台发布和高级打包选项。
安装
确保 flutter_distributor 已安装:
dart pub global activate flutter_distributor
配置文件
为高级打包配置所需的文件:
- macOS: - 如果打包 DMG 安装包: - macos/packaging/dmg/make_config.yaml- title: 应用名称 contents: - x: 448 y: 244 type: link path: "/Applications" - x: 192 y: 244 type: file path: 应用名称.app
- 如果打包 PKG 安装包: - macos/packaging/pkg/make_config.yaml- install-path: /Applications #sign-identity: <your-sign-identity>
- distribute_options.yaml- output: dist/
 
- Windows: - 如果打包 exe 安装包: - windows/packaging/exe/inno_setup.sas- [Setup] AppId={{APP_ID}} AppVersion={{APP_VERSION}} AppName={{DISPLAY_NAME}} AppPublisher={{PUBLISHER_NAME}} AppPublisherURL={{PUBLISHER_URL}} AppSupportURL={{PUBLISHER_URL}} AppUpdatesURL={{PUBLISHER_URL}} DefaultDirName={{INSTALL_DIR_NAME}} DisableProgramGroupPage=yes OutputDir=. OutputBaseFilename={{OUTPUT_BASE_FILENAME}} Compression=lzma SolidCompression=yes SetupIconFile={{SETUP_ICON_FILE}} WizardStyle=modern PrivilegesRequired={{PRIVILEGES_REQUIRED}} ArchitecturesAllowed=x64 ArchitecturesInstallIn64BitMode=x64 CloseApplications=force [Languages] {% for locale in LOCALES %} {% if locale == 'en' %}Name: "english"; MessagesFile: "compiler:Default.isl"{% endif %} {% if locale == 'hy' %}Name: "armenian"; MessagesFile: "compiler:Languages\\Armenian.isl"{% endif %} {% if locale == 'bg' %}Name: "bulgarian"; MessagesFile: "compiler:Languages\\Bulgarian.isl"{% endif %} {% if locale == 'ca' %}Name: "catalan"; MessagesFile: "compiler:Languages\\Catalan.isl"{% endif %} {% if locale == 'zh' %}Name: "chinesesimplified"; MessagesFile: "compiler:Languages\\ChineseSimplified.isl"{% endif %} {% if locale == 'co' %}Name: "corsican"; MessagesFile: "compiler:Languages\\Corsican.isl"{% endif %} {% if locale == 'cs' %}Name: "czech"; MessagesFile: "compiler:Languages\\Czech.isl"{% endif %} {% if locale == 'da' %}Name: "danish"; MessagesFile: "compiler:Languages\\Danish.isl"{% endif %} {% if locale == 'nl' %}Name: "dutch"; MessagesFile: "compiler:Languages\\Dutch.isl"{% endif %} {% if locale == 'fi' %}Name: "finnish"; MessagesFile: "compiler:Languages\\Finnish.isl"{% endif %} {% if locale == 'fr' %}Name: "french"; MessagesFile: "compiler:Languages\\French.isl"{% endif %} {% if locale == 'de' %}Name: "german"; MessagesFile: "compiler:Languages\\German.isl"{% endif %} {% if locale == 'he' %}Name: "hebrew"; MessagesFile: "compiler:Languages\\Hebrew.isl"{% endif %} {% if locale == 'is' %}Name: "icelandic"; MessagesFile: "compiler:Languages\\Icelandic.isl"{% endif %} {% if locale == 'it' %}Name: "italian"; MessagesFile: "compiler:Languages\\Italian.isl"{% endif %} {% if locale == 'ja' %}Name: "japanese"; MessagesFile: "compiler:Languages\\Japanese.isl"{% endif %} {% if locale == 'no' %}Name: "norwegian"; MessagesFile: "compiler:Languages\\Norwegian.isl"{% endif %} {% if locale == 'pl' %}Name: "polish"; MessagesFile: "compiler:Languages\\Polish.isl"{% endif %} {% if locale == 'pt' %}Name: "portuguese"; MessagesFile: "compiler:Languages\\Portuguese.isl"{% endif %} {% if locale == 'ru' %}Name: "russian"; MessagesFile: "compiler:Languages\\Russian.isl"{% endif %} {% if locale == 'sk' %}Name: "slovak"; MessagesFile: "compiler:Languages\\Slovak.isl"{% endif %} {% if locale == 'sl' %}Name: "slovenian"; MessagesFile: "compiler:Languages\\Slovenian.isl"{% endif %} {% if locale == 'es' %}Name: "spanish"; MessagesFile: "compiler:Languages\\Spanish.isl"{% endif %} {% if locale == 'tr' %}Name: "turkish"; MessagesFile: "compiler:Languages\\Turkish.isl"{% endif %} {% if locale == 'uk' %}Name: "ukrainian"; MessagesFile: "compiler:Languages\\Ukrainian.isl"{% endif %} {% endfor %} [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: {% if CREATE_DESKTOP_ICON != true %}unchecked{% else %}checkedonce{% endif %} Name: "launchAtStartup"; Description: "{cm:AutoStartProgram,{{DISPLAY_NAME}}}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: {% if LAUNCH_AT_STARTUP != true %}unchecked{% else %}checkedonce{% endif %} [Files] Source: "{{SOURCE_DIR}}\\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] Name: "{autoprograms}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}" Name: "{autodesktop}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}"; Tasks: desktopicon Name: "{userstartup}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}"; WorkingDir: "{app}"; Tasks: launchAtStartup [Run] Filename: "{app}\\{{EXECUTABLE_NAME}}"; Description: "{cm:LaunchProgram,{{DISPLAY_NAME}}}"; Flags: {% if PRIVILEGES_REQUIRED == 'admin' %}runascurrentuser{% endif %} nowait postinstall skipifsilent [Code] function InitializeSetup(): Boolean; var ResultCode: Integer; begin Exec('taskkill', '/F /IM 应用名称.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) Result := True; end;- windows/packaging/exe/make_config.yaml- app_id: 6L913538-42B1-4596-G479-BJ779F21A65D publisher: 应用名称 publisher_url: https://github.com/aaa/aaa display_name: 应用名称 executable_name: 应用名称.exe output_base_file_name: 应用名称.exe create_desktop_icon: true install_dir_name: "{autopf64}\\应用名称" setup_icon_file: ..\..\windows\runner\resources\app_icon.ico locales: - ar - en - fa - ru - pt - tr script_template: inno_setup.sas
- 如果打包 msix - windows/packaging/msix/make_config.yaml- display_name: 应用名称 publisher_display_name: 应用名称 identity_name: 应用名称.appioi msix_version: 2.5.7.0 logo_path: windows\runner\resources\app_icon.ico capabilities: internetClient, internetClientServer, privateNetworkClientServer languages: en-us, zh-cn, zh-tw, tr-tr,fa-ir,ru-ru,pt-br,es-es protocol_activation: 应用名称 execution_alias: 应用名称 certificate_path: windows\sign.pfx certificate_password: publisher: CN=8CB43675-F44B-4AA5-9372-E8727781BDC4 install_certificate: "false" enable_at_startup: "true" startup_task: parameters: --autostart
 
- Linux: - linux/packaging/appimage- 有两个文件 - linux/packaging/appimage/AppRun- #!/bin/bash cd "$(dirname "$0")" export LD_LIBRARY_PATH=usr/lib # Usage info show_help() { cat << EOF Usage: ${0##*/} ... start app or app, when no parameter is given, app is executed. -v show version EOF } show_version() { printf "app version " jq .version <./data/flutter_assets/version.json } # Initialize variables: service=0 #declare -i service OPTIND=1 # Resetting OPTIND is necessary if getopts was used previously in the script. # It is a good idea to make OPTIND local if you process options in a function. # if no arg is provided, execute app if [[ $# == 0 ]];then exec ./app else # processing arguments case $1 in appCli) exec ./appCli ${@:3} exit 0 ;; h) show_help exit 0 ;; v) show_version exit 0 ;; *) show_help >&2 exit 1 ;; esac fi- linux/packaging/appimage/make_config.yaml- display_name: App名称 icon: ./assets/images/source/ic_launcher_border.png keywords: - Hi generic_name: App名称 actions: - name: Start label: start arguments: - --start - name: Stop label: stop arguments: - --stop categories: - Network startup_notify: true app_run_file: AppRun # You can specify the shared libraries that you want to bundle with your app # # flutter_distributor automatically detects the shared libraries that your app # depends on, but you can also specify them manually here. # # The following example shows how to bundle the libcurl library with your app. # # include: # - libcurl.so.4 include: []
- linux/packaging/deb文件- linux/packaging/deb/make_config.yaml- display_name: Hiddify package_name: hiddify maintainer: name: hiddify email: linux@hiddify.com priority: optional section: x11 installed_size: 6604 essential: false icon: ./assets/images/source/ic_launcher_border.png postinstall_scripts: - echo "Installed Hiddify" postuninstall_scripts: - echo "Surprised Why?" keywords: - Hiddify - Proxy - VPN - V2ray - Nekoray - Xray - Psiphon - OpenVPN generic_name: Hiddify categories: - Network startup_notify: true
- linux/packaging/rpm- linux/packaging/rpm/make_config.yaml- display_name: App url: https://github.com/app/app-next/ license: Other packager: App packagerEmail: linux@App.com priority: optional section: x11 installed_size: 6604 essential: false icon: ./assets/images/source/ic_launcher_border.png keywords: - Hi generic_name: App group: Applications/Internet startup_notify: true
 
命令示例
- 打包 macOS (DMG 和 PKG) - flutter_distributor package --flutter-build-args=verbose --platform macos --targets dmg,pkg
- 打包 Windows (EXE 和 MSIX) - flutter_distributor package --flutter-build-args=verbose --platform windows --targets exe,msix
- 打包 Linux (DEB、RPM 和 AppImage) - flutter_distributor package --flutter-build-args=verbose --platform linux --targets deb,rpm,appimage
常见问题
1. 如何调试打包错误?
使用 -v 查看详细日志:
flutter build apk -v
 2. flutter_distributor 不工作?
确保 dart 的全局路径已配置:
export PATH="$PATH:$HOME/.pub-cache/bin"
3. 打包 Web 访问问题?
检查服务器配置是否正确,确保支持 HTML5 路由。
结语
通过本文档,您可以轻松完成 Flutter 多平台应用的打包与发布。高级用户还可以利用 flutter_distributor 工具实现更复杂的打包需求。如有问题,请参考 Flutter 官方文档 或加入社区寻求帮助。
- 准备工作
- Android 打包
- iOS 打包
- Web 打包
- Windows 打包
- macOS 打包
- Linux 打包
- 高级功能:flutter_distributor
- 安装
- 配置文件
- 命令示例
- 常见问题
- 1. 如何调试打包错误?
- 2. flutter_distributor 不工作?
- 3. 打包 Web 访问问题?
- 结语