系统中的所有组件都会组成一个已启用 root 权限的 组件实例树。树中的父组件负责 将其他组件的实例声明为其子组件并提供这些组件 功能。同时,子组件可以公开各种功能 返回给父级。这些组件实例和功能关系 设置组件拓扑。
在树中,任何父级组件及其所有子级构成一个组,称为 realm。借助 Realm,父级可以控制哪些功能会流入和流出其组件子树,从而创建功能边界。这个 通过封装,我们可以在内部重新组织领域,而不会影响 依赖于其公开的功能。
在上图中,fuchsia.example.Foo
的协议功能被路由
通过组件实例树从提供程序传输到客户端组件
使用 use
关键字声明其所需功能:
{
// Information about the program to run.
program: {
// Use the built-in ELF runner to run core binaries.
runner: "elf",
// The binary to run for this component.
binary: "bin/client",
},
// Capabilities required by this component.
use: [
{ protocol: "fuchsia.example.Foo" },
],
}
组件使用
capabilities
部分。这样一来,
其提供程序是组件框架已知的请参阅以下 provider.cml
示例:
{
// Information about the program to run.
program: {
// Use the built-in ELF runner to run core binaries.
runner: "elf",
// The binary to run for this component.
binary: "bin/provider",
},
// Capabilities provided by this component.
capabilities: [
{ protocol: "fuchsia.example.Foo" },
],
// Capabilities routed through this component.
expose: [
{
protocol: "fuchsia.example.Foo",
from: "self",
},
],
}
expose
关键字使相应功能可将功能从此组件提供给其他组件
这些领域,其中可能还包括此
子组件的子级。在本例中, capability 的来源为 self
因为此组件是提供程序
父级组件控制领域内的 capability 路由,从客户端组件到提供程序创建显式路径。请参阅以下内容
parent.cml
清单示例:
{
children: [
{
name: "provider",
url: "fuchsia-pkg://fuchsia.com/foo-package#meta/provider.cm",
},
{
name: "client",
url: "fuchsia-pkg://fuchsia.com/foo-package#meta/client.cm",
},
],
offer: [
{
protocol: "fuchsia.example.Foo",
from: "#provider",
to: [ "#client" ],
},
],
}
父组件声明 Realm 中的子组件集,
使用 offer
关键字向它们路由功能。这样,父级
确定每个子级功能的范围和来源。这还支持拓扑中的多个组件提供相同的功能,因为组件框架依赖于显式路由来确定如何解析来自每个客户端的请求。
功能类型
Fuchsia 组件支持许多不同类型的功能。到目前为止,本模块中的示例展示了两种不同的 capability 类型:runner
和 protocol
。您可能已经注意到,protocol
capability 需要路由路径,但 runner
capability 不需要。
有些功能由其父级显式路由到组件,而 使用 environments。环境使框架能够预配功能 这样毫无意义。默认情况下 组件会继承其父级的环境。组件还可以声明 为孩子打造全新的环境
下表列出了组件可用的功能类型, 以及它们是必须从父组件显式路由,还是 由环境提供:
类型 | 说明 | 提供方 |
---|---|---|
directory
|
其他组件提供的共享文件系统目录。 | 路由 |
event
|
由组件管理器生成的事件,例如组件启动或功能请求。 | 路由 |
protocol
|
其他组件或框架提供的 FIDL 协议。 | 路由 |
resolver
|
一种组件,能够解析指向组件清单的网址。 | 环境 |
runner
|
用于执行特定组件的运行时。 | 环境 |
service
|
执行常规任务的相关 FIDL 协议的命名组。 | 路由 |
storage
|
每个组件的独立文件系统目录都是唯一的。 | 路由 |
识别组件
组件通过网址进行标识。该框架将组件网址解析为 组件解析器进行组件声明。解析器本身就是组件,能够处理特定网址方案并提取组件清单、程序和资源。
大多数组件都是在 Fuchsia 软件包中发布,因此组件网址是 对该软件包内的组件清单的引用。请参阅以下示例:
fuchsia-pkg://fuchsia.com/foo-package#meta/foo-component.cm
组件实例由拓扑路径引用(称为标识名)标识。组件的标识符以绝对路径或相对路径的形式指示其在组件实例树中的位置。例如,名称路径
/core/system-updater
是指已存在的 system-updater
实例
在 core
领域中。
组件生命周期
在添加和移除组件实例时,组件实例会随之创建和销毁 在组件拓扑中可能通过以下两种方式之一发生:
- 静态:在组件清单中将实例声明为子实例 另一个组件的创建。静态组件只会创建并 在更新更改组件拓扑时被销毁。
- 动态:在组件
collection
中添加或移除实例 在运行时使用fuchsia.component.Realm
协议。动态组件 它们会在系统关闭时被销毁
组件销毁后,框架将移除其持久状态 (例如本地存储)。
当另一个组件尝试执行下列操作时,框架将启动一个组件实例: 打开相应的频道当连接到 相应功能连接到组件 会重复使用正在运行的实例
组件可通过退出程序(由
组件的 runner
),或者框架可能会在出现以下情况时停止该组件:
系统关闭。
练习:集成组件
要调用组件,组件必须存在于有效
组件拓扑在本练习中,您将向
ffx-laboratory
- 用于开发的受限集合,
产品的核心领域。通过集合,组件可以动态地
是在运行时创建和销毁的
启动模拟器
如果您还没有运行的实例,请启动具有网络支持的 FEMU:
ffx emu start workstation_eng.x64 --headless
发布软件包
与软件交付相关的召回 Fuchsia 设备通过软件包代码库按需解析软件包。
使用 bazel run
命令构建和发布 echo
组件软件包:
bazel run //fuchsia-codelab/echo:pkg.publish -- \
--repo_name fuchsiasamples.com
此命令将软件包发布到名为 fuchsiasamples.com
的代码库;
创建代码库(如果不存在)并使用目标注册该代码库。
添加到组件拓扑
使用以下命令创建 echo
组件的新实例:
ffx component create /core/ffx-laboratory:echo \
fuchsia-pkg://fuchsiasamples.com/echo-example#meta/echo.cm
此命令接受两个参数:
/core/ffx-laboratory:echo
:这是组件名称, 表示组件实例的组件拓扑内的路径。fuchsia-pkg://fuchsiasamples.com/echo-example#meta/echo.cm
:这是 组件网址,指示 Fuchsia 应如何从 软件包服务器。
拓扑中现在存在一个名为 echo
的新组件实例。显示
新实例的详细信息:
ffx component show echo
您应该会看到以下输出内容:
Moniker: /core/ffx-laboratory:echo
URL: fuchsia-pkg://fuchsiasamples.com/echo-example#meta/echo.cm
Type: CML dynamic component
Component State: Unresolved
Execution State: Stopped
请注意,实例已创建,但组件网址尚未 已解决。当框架尝试启动实例时,就会发生解析。
启动组件实例
使用以下命令启动新的 echo
组件实例:
ffx component start /core/ffx-laboratory:echo
此命令接受一个参数:
/core/ffx-laboratory:echo
:这是组件名称, 表示组件实例的组件拓扑内的路径。
这会使组件实例启动,在日志中输出问候语。 然后退出。打开一个新的终端窗口,然后过滤设备日志以查找示例中的相关消息:
ffx log --filter echo
您应该会在设备日志中看到以下输出:
[ffx-laboratory:echo][I] Hello, Alice, Bob, Spot!
探索实例
使用以下命令再次显示 echo
实例的详细信息:
ffx component show echo
您现在应看到以下输出:
Moniker: /core/ffx-laboratory:echo
URL: fuchsia-pkg://fuchsiasamples.com/echo-example#meta/echo.cm
Type: CML dynamic component
Component State: Resolved
Incoming Capabilities: fuchsia.logger.LogSink
pkg
Execution State: Stopped
组件状态已更改为 Resolved
,您可以看到更多详情
组件功能
组件没有访问系统其他部分的环境感知功能。 组件需要的每项功能都必须通过 组件拓扑或由其环境提供。
echo
组件需要 fuchsia.logger.LogSink
capability 才能写入系统日志。您已成功查看日志输出
因为此功能是提供给 ffx-laboratory
中的组件的
来自 core
大区的合集:
{
collections: [
{
name: "ffx-laboratory",
},
],
offer: [
{
protocol: [ "fuchsia.logger.LogSink" ],
from: "parent",
to: "#ffx-laboratory",
},
],
}
<ph type="x-smartling-placeholder">
销毁实例
使用以下命令清理 echo
实例:
ffx component destroy /core/ffx-laboratory:echo