本文档演示了如何在开发期间直接将组件添加到组件实例树,以及如何在运行时与这些组件进行交互。
组件框架,以便针对特定用例提供一些抽象。如果您使用以下某个框架构建组件,请改为参阅相应的指南:
- 会话组件:构建和运行会话
- 测试组件:运行 Fuchsia 测试
概念
在运行组件之前,您应了解以下概念:
- 将各个组件实例以父子关系的层次结构关联起来。
- 组件实例会经历四个主要生命周期状态:创建、启动、停止和销毁。
- 组件标识符:使用拓扑路径标识树中的组件实例。
- 组件清单中,或在运行时在组件集合中动态创建。每个实例都由组件
name
和url
组成。 - 组件网址:用于标识组件。组件网址由组件框架解析,通常解析为软件包内的资源。
如需详细了解组件执行,请参阅组件生命周期。
组件实例
运行组件的第一步是将新的组件实例添加到树中。capabilities
探索静态组件
静态组件会声明为树中其他组件实例的子级。您可以使用 ffx component show
确定静态组件实例的标识名和组件网址:
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
创建新的组件实例,在现有集合中提供目标别名,并提供用于解析组件的组件网址:
ffx component create TARGET_MONIKER COMPONENT_URL
将 TARGET_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
通过提供其标识名来销毁动态组件实例:
ffx component destroy TARGET_MONIKER
将 TARGET_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
可使用其标识名终止正在运行的组件实例的执行:
ffx component stop TARGET_MONIKER
将 TARGET_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
替换为现有合集中新组件的目标标识名,将 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
更新组件的方式
更改组件时,您通常需要更新设备上运行的某个实例。例如,您可以更改组件的二进制文件,然后重启组件以使用新二进制文件运行。或者,您可以更改其清单以添加新的 capability 路线,并希望在设备上提供这些 capability 路线。
ffx component reload
命令是重新加载组件最快捷、最完整的方式。但这并不是唯一的方法,了解其他方法有助于针对特殊用例执行更精确的操作。
下面简要介绍了这些方法,并在下文中进行了详细说明。
摘要
命令 | 说明 | 更新软件包 | 更新清单 | 节省资源 |
---|---|---|---|---|
ffx 组件重新加载 | 停止、更新和启动 | 是 | 是 | 是 |
ffx 组件毁掉/创建/启动 | 销毁,然后启动 | 是 | 是 | 否 |
ffx component run --recreate | 销毁,然后启动 | 是 | 是 | 否 |
ffx 组件停止/启动 | 停止和启动,而不会销毁 | 否 | 否 | 是 |
- “更新软件包”表示在重新加载软件包时更新代码。
- “更新清单”表示重新加载清单缓存,更新 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
与销毁/创建/启动序列类似的便捷命令是带有 --recreate
的 run
命令:
ffx component run TARGET_MONIKER COMPONENT_URL --recreate
停止/启动
虽然这不是进行更新的主要方式,但仅停止然后启动组件的一个副作用是,它将部分更新。
$ ffx component stop TARGET_MONIKER
$ ffx component start TARGET_MONIKER
假设 ffx serve
等软件包管理器正在运行,系统会加载并运行组件的最新版本代码。不过,由于缓存在 Fuchsia 组件框架中的运作方式,清单不会更新。该清单包含 *.cm
文件中定义的组件的路由和其他信息。因此,如果您更改组件的 capability 路线,停止和启动组件将不会捕获这些更改。
ffx-laboratory
ffx-laboratory
是一个组件集合,可提供一组受限的开发功能。此集合中的组件可使用以下功能:
- 协议功能
fuchsia.logger.LogSink
:记录日志消息fuchsia.process.Launcher
:创建新进程
- 存储功能
tmp
:临时存储(非永久性)data
:由/tmp
支持的模拟永久性存储cache
:由/tmp
支持的模拟缓存存储
- 目录功能
/dev
:驱动程序管理器提供的设备驱动程序devfs
/boot
:组件管理器提供的只读bootfs
ffx-laboratory
是 transient
集合。此集合中的组件实例在停止后也会保留。如需销毁此集合中的组件实例,请使用 ffx component destroy
命令。
问题排查
本部分介绍了您在开发期间运行组件时可能会遇到的常见问题。
无法解析组件
使用 ffx component start
或 ffx 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 create
或 ffx 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.
如果目标标识符已被其他组件实例使用,就会发生这种情况。
如需解决此问题,请使用 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...