意图
这与在移动操作系统中使用的意图概念类似,应用程序管理器中的意图系统建立在应用程序与系统 UI 之间具有轻量级进程间通信 (IPC) 机制的思想之上,而不需要硬编码耦合或甚至编译时依赖项。意图本身是发件应用程序希望系统中最能执行该操作的部分执行的操作描述。确保将这些意图请求路由到正确的接收者是应用程序管理器的责任。一个非常简单的例子是 showImage
意图,其中发送应用程序可以请系统显示图像文件:如果系统安装了图像查看器应用程序,并注册了自己来处理 showImage
意图,那么任何应用程序都可以显示图像文件,而无需了解图像查看器应用程序的任何具体信息。
Android 文档 对这一概念也有很好的介绍。
应用程序管理器对意图的处理方法
应用程序管理器对意图的处理方法非常简单:虽然(仍然)与其他解决方案相比缺乏一些功能。例如,二进制数据或系统广播的支持。然而,与其他解决方案相比,它提供了一个非常简单且直接的 API。
注意:虽然移动操作系统为您提供了意图 机制 及所有已定义的 意图 API 的描述,但应用程序管理器只提供机制。这与其他应用程序管理器中使用的模块中使用的哲学一致,其中系统 UI 负责定义系统的接口和行为。
意图术语
以下是一些术语,有助于理解意图请求中涉及的所有 IDs 之间的区别
intentId
:意图的名称或类。在复杂系统中,在这里使用反向 DNS 表示法是有意义的,例如io.qt.openUrl
。requestId
:用于在整个系统中追踪意图请求的 UUID,因为它们跨越了系统 UI 和最多两个应用程序之间的进程边界。applicationId
表示负责处理请求的应用程序。这直接映射到 ApplicationObject::id 值。如果处理应用程序确实是系统 UI,则该 ID 将具有特殊的值 IntentClient::systemUiId (:sysui:
)。requestingApplicationId
执行与applicationId
相同的操作,但对于发送请求的应用程序。如果发送请求的应用程序确实是系统 UI,则该 ID 将具有特殊的值 IntentClient::systemUiId (:sysui:
)。
可以在意图请求(见 IntentClient::sendIntentRequest)和意图请求回复(见 IntentRequest::sendReply)中附加任意数据。
警告:这些数据需要首先将 JavaScript 对象序列化为底层的 IPC 传输,然后在接收端反序列化回 JavaScript 对象。建议将参数和结果对象中使用的类型限制为 JSON 类型。
意图注册
每个应用程序在其 info.yaml
清单文件中定义它可以处理的意图。请注意,打包工具和应用程序管理器都无法验证清单文件中的意图 ID 是否针对您的特定项目有效。
系统 UI 本身也可以注册意图:在这种情况下不需要单独的清单文件,而是 QML 处理器对象本身将负责提供注册所需的数据;请参阅 下一节。
应用程序管理器在启动时(以及在运行时安装应用程序时)解析所有这些清单文件。只有应用程序管理器和系统 UI 可以访问所有应用程序定义的所有已注册意图的完整列表;出于安全和隐私的原因,应用程序自身无法访问此列表。
在 QML 中处理意图
为了在您的 QML 应用程序内部处理意图,您必须为在您的清单文件中定义的所有意图实例化 IntentHandler 项目。确保这些项目与应用程序 QML 根对象一起构造,并且在之后永不删除。
任何传入的意图请求都将与应用程序和系统 UI 中先前注册的所有意图进行匹配。当应用程序管理器确定您的应用程序负责处理此类意图时,它将首先启动您的应用程序(如果尚未运行),然后将在应用程序侧发出适当的 IntentHandler's requestReceived 信号。对那些传入请求的回复可以是同步的,也可以是异步的。
至于在系统 UI 中处理意图:您必须实例化 IntentServerHandler 项目,而不是创建 IntentHandler 项目。实际上,IntentServerHandler 是从 IntentHandler 派生的,因此它与其应用程序侧的对应项以相同的方式工作:它仅添加所需的属性来定义所有元数据(例如 names
,icon
,...),而对于应用程序,这些是通过清单文件提供的。
在 QML 中创建意图请求
想要发送意图请求的应用程序可以通过调用工厂函数 IntentClient::sendIntentRequest 来这样做。这些请求不能通过其他方式创建。该请求将立即发送到系统,然后可以返回 IntentRequest 对象来跟踪此请求的完成和可能的结果值。
在系统 UI 中,您可以使用完全相同的机制来创建和跟踪意图请求。
在系统界面中区分意图请求
如果传入的意图请求可能被多个应用程序处理,应用程序管理器会联系系统界面来区分请求并选择一个应用程序。系统界面可以通过连接到IntentServer::disambiguationRequest()信号,然后通过acknowledgeDisambiguationRequest选择可能的应用程序进行响应。如果请求根本无法区分,还可以通过rejectDisambiguationRequest拒绝请求。
系统界面中的IntentModel
虽然应用程序只知道自己的意图,但系统界面可以通过IntentServer单例和IntentModel类完全访问所有已注册意图的元数据。与ApplicationManager单例和ApplicationModel类类似,IntentServer是系统的单例,持有所有数据,而IntentModel类则提供了一个方便的模型界面,对原始数据进行排序和筛选。
通过使用这些模型接口,可以替换通常在ApplicationModel上运行的经典启动器网格,使用一个利用IntentModel的版本,使应用程序通过包括参数在内的特定意图请求隐式启动,而不仅仅是调用ApplicationObject::start()函数。
本地应用程序的意图
意图机制使用D-Bus作为系统界面和应用程序进程之间的传输协议。D-Bus接口在文件src/dbus-lib/io.qt.applicationmanager.intentinterface.xml
中定义。D-Bus API与QML API非常相似。意图、应用程序和请求ID以字符串形式发送,而参数则在JavaScript对象和D-Bus a{sv}
变体字典之间转换。
如果您使用应用程序管理器的便捷applicationmain-lib
作为您的原生和QML混合应用程序的基本构建模块,那么所有D-Bus处理都已经为您实现,您可以使用上述描述的IntentHandler项。
© 2024 The Qt Company Ltd. 本文档的贡献版权属于其各自的所有者。本提供的文档根据自由软件基金会发布的GNU自由文档许可证版本1.3的条款进行许可。Qt及其相应标志是The Qt Company Ltd.在芬兰和其他国家的商标。所有其他商标均为其各自所有者的财产。