在典型的开发周期中,您会在命令行中使用 flutter run 测试应用,或者使用 IDE 中的运行调试选项。默认情况下,Flutter 会构建应用的调试版本。

当您准备好构建应用的发布版本时,例如要发布到 Snap Store其他渠道,本页面可以为您提供帮助。

先决条件

#

要构建并发布到 Snap Store,您需要以下组件:

设置构建环境

#

使用以下说明设置您的构建环境。

安装 snapcraft

#

在命令行中,运行以下命令:

sudo snap install snapcraft --classic

安装 LXD

#

要安装 LXD,请使用以下命令:

sudo snap install lxd

在 snap 构建过程中需要 LXD。安装完成后,需要配置 LXD 以供使用。默认答案适用于大多数用例。

sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty disk or partition? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=5GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

首次运行时,LXD 可能无法连接到其套接字。

An error occurred when trying to communicate with the 'LXD'
provider: cannot connect to the LXD socket
('/var/snap/lxd/common/lxd/unix.socket').

这意味着您需要将您的用户名添加到 LXD (lxd) 组,然后退出并重新登录您的会话。

sudo usermod -a -G lxd <your username>

snapcraft 概述

#

snapcraft 工具根据 snapcraft.yaml 文件中的说明构建 snap。要基本了解 snapcraft 及其核心概念,请查看Snap 文档Snapcraft 入门介绍。其他链接和信息在此页面底部列出。

Flutter snapcraft.yaml 示例

#

将 YAML 文件放在 Flutter 项目的 <project root>/snap/snapcraft.yaml 下。(请记住 YAML 文件对空格敏感!)例如:

yaml
name: super-cool-app
version: 0.1.0
summary: Super Cool App
description: Super Cool App that does everything!

confinement: strict
base: core22
grade: stable

slots:
  dbus-super-cool-app: # adjust accordingly to your app name
    interface: dbus
    bus: session
    name: org.bar.super_cool_app # adjust accordingly to your app name and
    
apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome] # gnome includes the libraries required by flutter
    plugs:
    - network
    slots:
      - dbus-super-cool-app
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # The main entry-point file of the application

以下各部分将解释 YAML 文件的不同部分。

元数据

#

snapcraft.yaml 文件中的此部分定义并描述了应用程序。snap 版本是从构建部分派生(采用)的。

yaml
name: super-cool-app
version: 0.1.0
summary: Super Cool App
description: Super Cool App that does everything!

Grade、confinement 和 base

#

此部分定义了 snap 的构建方式。

yaml
confinement: strict
base: core22
grade: stable
Grade
指定 snap 的质量;这与后面的发布步骤相关。
Confinement
指定 snap 在最终用户系统上安装后将拥有的系统资源访问级别。严格的 confinement 将应用程序访问限制在特定资源(在 app 部分的 plugs 中定义)。
Base
Snaps 被设计为自包含的应用程序,因此它们需要自己的私有核心根文件系统,称为 basebase 关键字指定用于提供最小公共库集并作为应用程序运行时根文件系统的版本。

Apps

#

此部分定义了存在于 snap 中的应用程序。一个 snap 可以有一个或多个应用程序。此示例有一个应用程序——super_cool_app。

yaml
apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome]
Command

指向二进制文件(相对于 snap 的根目录),并在调用 snap 时运行。

Extensions

一个或多个扩展的列表。Snapcraft 扩展是可重用组件,可以在构建和运行时将库和工具集暴露给 snap,而无需开发人员了解包含的框架。gnome 扩展将 GTK 3 库暴露给 Flutter snap。这确保了更小的占位符和更好的与系统的集成。

Plugs

一个或多个系统接口 plugs 的列表。在 snap 被严格限制时,需要这些接口来提供必要的功能。此 Flutter snap 需要访问网络。

DBus 接口

DBus 接口提供了一种 snap 通过 DBus 进行通信的方式。提供 DBus 服务的 snap 声明一个具有知名 DBus 名称的 slot 以及它使用的总线。想要与提供 snap 的服务通信的 snap 声明一个提供 snap 的 plug。请注意,需要一个 snap 声明才能通过 snap store 分发您的 snap 并声明此知名 DBus 名称(只需将 snap 上传到 store 并请求手动审核,审核员将进行查看)。

当安装了提供 snap 时,snapd 将生成安全策略,允许它在指定总线上监听知名 DBus 名称。如果指定了系统总线,snapd 还将生成 DBus 总线策略,允许“root”拥有该名称,并允许任何用户与服务通信。非 snap 进程可以通过传统的权限检查与提供 snap 进行通信。其他(消费)snap 可能仅通过连接 snap 的接口来与提供 snap 通信。

dbus-super-cool-app: # adjust accordingly to your app name
  interface: dbus
  bus: session
  name: dev.site.super_cool_app

Parts

#

此部分定义了组装 snap 所需的源。

Parts 可以使用插件自动下载和构建。与扩展类似,snapcraft 可以使用各种插件(如 Python、C、Java 和 Ruby)来协助构建过程。Snapcraft 还提供了一些特殊插件。

nil 插件
不执行任何操作,实际的构建过程通过手动覆盖来处理。
flutter 插件
提供必要的 Flutter SDK 工具,以便您无需手动下载和设置构建工具即可使用它。
yaml
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # The main entry-point file of the application

桌面文件和图标

#

桌面条目文件用于将应用程序添加到桌面菜单。这些文件指定应用程序的名称和图标、所属的类别、相关的搜索关键字等。这些文件具有 .desktop 扩展名,并遵循 XDG Desktop Entry Specification 1.1 版本。

Flutter super-cool-app.desktop 示例

#

将 .desktop 文件放在 Flutter 项目的 <project root>/snap/gui/super-cool-app.desktop 下。

注意:图标和 .desktop 文件名必须与 yaml 文件中的应用程序名称相同!

例如

yaml
[Desktop Entry]
Name=Super Cool App
Comment=Super Cool App that does everything
Exec=super-cool-app 
Icon=${SNAP}/meta/gui/super-cool-app.png # Replace name with your app name.
Terminal=false
Type=Application
Categories=Education; # Adjust accordingly your snap category.

将具有 .png 扩展名的图标放在 Flutter 项目的 <project root>/snap/gui/super-cool-app.png 下。

构建 snap

#

一旦 snapcraft.yaml 文件完成,请从项目根目录运行 snapcraft,如下所示:

要使用 Multipass VM 后端:

snapcraft

要使用 LXD 容器后端:

snapcraft --use-lxd

测试 snap

#

snap 构建完成后,您将在项目根目录中获得一个 <name>.snap 文件。

$ sudo snap install ./super-cool-app_0.1.0_amd64.snap --dangerous

发布

#

您现在可以发布 snap 了。该过程包括以下步骤:

  1. 如果您还没有开发者帐户,请在 snapcraft.io 上创建一个。
  2. 注册应用程序的名称。注册可以通过 Snap Store Web UI 门户完成,也可以通过命令行完成,如下所示:
    snapcraft login
    snapcraft register
  3. 发布应用程序。在阅读下一部分了解如何选择 Snap Store 渠道后,将 snap 推送到 store:
    snapcraft upload --release=<channel> <file>.snap

Snap Store 渠道

#

Snap Store 使用渠道来区分不同版本的 snap。

snapcraft upload 命令将 snap 文件上传到 store。但是,在运行此命令之前,您需要了解不同的发布渠道。每个渠道包含三个组件:

Track
所有 snap 都必须有一个名为 latest 的默认 track。除非另有说明,否则这就是隐含的 track。
Risk
定义应用程序的准备程度。Snap Store 中使用的风险级别为:stablecandidatebetaedge
Branch
允许创建短期 snap 序列来测试 bug 修复。

Snap Store 自动审核

#

Snap Store 会对您的 snap 运行几项自动化检查。根据 snap 的构建方式以及是否存在任何特定的安全问题,也可能需要进行手动审核。如果检查顺利通过,snap 将在 store 中可用。

其他 snapcraft 资源

#

您可以在 snapcraft.io 网站上的以下链接中了解更多信息:

其他部署资源

#

一个一站式 Flutter 应用程序打包和分发工具,为您提供满足各种分发需求的解决方案。

支持 appimage、deb、pacman、rpm 等流行的打包格式。

适用于 Flutter 应用离线构建的 Flatpak manifest 工具。

支持 Flatpak 在 Flathub 上发布的准备工作。