运行组件

本文档演示了如何在开发期间直接向组件实例树添加组件,并在运行时与这些组件进行交互。

Fuchsia 在 组件框架之上为特定使用情形提供了一些抽象。如果您要使用以下框架之一构建组件,请改用相应的指南:

概念

在运行组件之前,您应该了解以下概念:

如需详细了解组件执行,请参阅组件生命周期

组件实例

运行组件的第一步是将新的组件实例添加到树中。树中组件实例的位置决定了其可用的功能

探索静态组件

静态组件在树中声明为另一个组件实例的子级。您可以使用 ffx component show 确定静态组件实例的 moniker 和组件网址:

ffx component show COMPONENT_NAME

COMPONENT_NAME 替换为组件的名称。以下示例展示了 pkg-resolver 组件的命令输出:

$ ffx component show pkg-resolver
               Moniker: /core/pkg-resolver
                   URL: fuchsia-pkg://fuchsia.com/pkg-resolver#meta/pkg-resolver.cm
                  Type: CML static component
       Component State: Resolved
       Execution State: Running
...

无法在运行时创建或销毁静态组件实例。

管理动态组件

动态组件是在集合的运行时创建的。您可以使用 ffx component create 创建新的组件实例,在现有集合中提供目标 moniker 和用于解析组件的组件网址:

ffx component create TARGET_MONIKER COMPONENT_URL

TARGET_MONIKER 替换为现有集合中新组件的目标 moniker,并将 COMPONENT_URL 替换为组件的提供位置。例如,以下命令会在 ffx-laboratory 集合中创建一个名为 hello-world 的新组件实例:

$ ffx component create /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
URL: fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...

同样,您可以使用 ffx component destroy 通过提供动态组件实例的 moniker 来销毁该实例:

ffx component destroy TARGET_MONIKER

TARGET_MONIKER 替换为要销毁的组件的 Moniker。以下示例会销毁上面创建的 hello-world 组件:

$ ffx component destroy /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Destroying component instance...

组件执行

一旦组件实例存在于树中,您就可以使用 ffx component 启动和停止目标实例。

启动实例

使用 ffx component start 显式启动组件实例:

ffx component start TARGET_MONIKER

TARGET_MONIKER 替换为要启动的组件的别名。以下示例启动了之前创建的 hello-world 组件:

$ ffx component start /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Starting component instance...

停止实例

使用 ffx component stop 可通过正在运行的组件实例的 moniker 终止其执行:

ffx component stop TARGET_MONIKER

TARGET_MONIKER 替换为要停止的组件的 moniker。以下示例会停止上面启动的 hello-world 组件:

$ ffx component stop /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Stopping component instance...

运行组件

ffx component run 命令提供了一个快速入门指南,用于在开发期间运行基本组件。它是 ffx component create 后跟 ffx component start 的快捷方式:

ffx component run TARGET_MONIKER COMPONENT_URL

TARGET_MONIKER 替换为现有集合中新组件的目标 moniker,并将 COMPONENT_URL 替换为组件的提供位置。例如,以下命令会在 ffx-laboratory 集合中创建一个名为 hello-world-rust 的新组件实例:

$ ffx component run /core/ffx-laboratory:hello-world-rust fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
URL: fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
Moniker: /core/ffx-laboratory:hello-world-rust
Creating component instance...
Starting component instance...

上述示例相当于运行以下各个 ffx 命令:

$ ffx component create /core/ffx-laboratory:hello-world-rust fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
$ ffx component start /core/ffx-laboratory:hello-world-rust

更新组件的方式

当您更改组件时,通常会希望更新设备上运行的相应实例。例如,您可以更改组件的二进制文件,然后重启组件以使用新的二进制文件运行。或者,您可能更改了其清单以添加新的功能路由,并希望在设备上提供这些功能路由。

ffx component reload 命令是重新加载组件的最快、最完整的方法。但这不是唯一的方法,了解其他方法可能有助于在特殊使用情形下进行更精确的操作。

下文将对这些方法进行总结并详细说明。

摘要

命令 说明 更新 软件包 更新清单 节省资源
ffx 组件重新加载 停止、更新和启动
ffx 组件销毁/创建/启动 销毁,然后启动
ffx component run --recreate 销毁,然后启动
ffx component stop/start 停止和启动,而不会销毁
  • “更新软件包”是指在重新加载软件包时更新代码。
  • “更新清单”是指重新加载清单缓存,从而更新 FIDL 文件中包含的路由和其他信息。
  • “保留资源”是指保留本应通过销毁命令释放的资源(例如存储空间)。

重新加载

在保留资源的情况下更新组件的代码和清单:

ffx component reload TARGET_MONIKER

此命令会先关闭组件,然后重新加载并重启组件。该命令会更新软件包和清单,而不会销毁组件或释放资源。

reload 命令会保留组件的资源,例如存储空间。如果很难在特定状态下初始化、获取或重新创建资源以进行调试,那么这种保留功能会很有用。

当销毁组件的成本较高时(例如需要关闭并重启会话或目标设备/模拟器时),重新加载的速度也会更快。

销毁/创建/启动

如需完全重新加载组件并舍弃已获取的资源,您可以先销毁现有组件实例,然后再重新启动它。使用:

$ ffx component destroy TARGET_MONIKER
$ ffx component create TARGET_MONIKER COMPONENT_URL
$ ffx component start TARGET_MONIKER

此序列将重新加载软件包和清单,因此代码和功能变更将得到更新。不过,销毁组件也会释放其使用的所有资源。如果您希望从完全重新初始化的组件开始,那么此完全重置可能正是您想要的。

运行 --recreate

与销毁/创建/启动序列类似的便捷命令是带有 --recreaterun 命令:

ffx component run TARGET_MONIKER COMPONENT_URL --recreate

停止/启动

虽然这并不是更新组件的主要方式,但停止并启动组件的副作用是它会部分更新。

$ ffx component stop TARGET_MONIKER
$ ffx component start TARGET_MONIKER

假设正在运行 ffx serve 等软件包管理器,则会加载并运行组件代码的最新版本。不过,由于 Fuchsia 组件框架中的缓存工作方式,清单不会更新。清单包含组件的路由和 *.cm 文件中定义的其他信息。因此,如果您更改了组件的功能路由,停止并启动组件将不会采用这些更改。

ffx-laboratory

ffx-laboratory 是一个组件集合,可为开发提供一组受限的功能。此集合中的组件可使用以下功能:

  • 协议功能
  • 存储功能
    • tmp:临时存储空间(非持久性)
    • data:由 /tmp 支持的模拟永久性存储空间
    • cache:由 /tmp 支持的模拟缓存存储空间
  • 目录功能
    • /boot:由组件管理器提供的只读 bootfs

ffx-laboratorytransient 集合。此集合中的组件实例即使在停止后也会继续存在。如需销毁此集合中的组件实例,请使用 ffx component destroy 命令。

问题排查

本部分介绍了在开发期间运行组件时可能会遇到的一些常见问题。

无法解析组件

使用 ffx component startffx component run 时,如果组件框架无法解析组件实例,您可能会遇到以下错误:

$ ffx component run /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
Starting component instance...
Lifecycle protocol could not bind to component instance: InstanceCannotResolve

如果组件网址无法解析为有效的组件清单,就会发生此错误。

如需解决此问题,请验证以下各项:

组件实例已存在

使用 ffx component createffx component run 时,如果组件实例已存在,您可能会遇到以下错误:

$ ffx component run /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
Component instance already exists. Use --recreate to destroy and recreate a new instance, or --name to create a new instance with a different name.

当目标 Moniker 已被其他组件实例使用时,就会发生这种情况。

如需解决此问题,请使用 ffx component destroy 命令手动销毁实例:

$ ffx component destroy /core/ffx-laboratory:hello-world
Moniker: /core/ffx-laboratory:hello-world
Destroying component instance...

如果您使用的是 ffx component run,请添加 --recreate 标志以销毁实例并重新创建:

$ ffx component run /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm --recreate
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world
Creating component instance...
Component instance already exists. Destroying...
Recreating component instance...
Starting component instance...

或者,添加 --name 标志以创建具有不同名称的新实例:

$ ffx component run /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm --name hello-world-2
URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world.cm
Moniker: /core/ffx-laboratory:hello-world-2
Creating component instance...
Starting component instance...