鸿蒙进阶——Framework之Want 隐式匹配机制概述

文章大纲

  • 引言
  • 一、Want概述
  • 二、Want的类型
    • 1、显式Want
    • 2、隐式Want
    • 3、隐式Want的匹配
  • 三、隐式启动Want 源码概述
    • 1、有且仅有一个Ability匹配
    • 2、有多个Ability 匹配需要弹出选择对话框
    • 3、ImplicitStartProcessor::ImplicitStartAbility
        • 3.1、GenerateAbilityRequestByAction
          • 3.1.1、GetBundleManagerHelper 获取BMS对象
          • 3.1.2、GetBundleManagerHelper()->ImplicitQueryInfos
          • 3.1.3、ImplicitStartProcessor::FilterAbilityList
        • 3.2、定义回调
        • 3.3、根据dialogAppInfos和deviceType的组合进行不同的分支处理
      • 4、当有多个匹配结果时会先执行FilterAbilityList(有条件执行)
  • 小结

引言

在Android 中Activity及其他四大组件之间是通过Intent来传递信息的,在我们的鸿蒙操作系统中同样有自己组件的“Intent”,今天我们介绍下鸿蒙中的“Intent”。

暂且对照着Android中的Intent 来理解。

一、Want概述

Want 是对象间信息传递的载体,可以用于应用组件间的信息传递。其使用场景之一是作为startAbility()的参数,包含了指定的启动目标以及启动时需携带的相关数据,如bundleName和abilityName字段分别指明目标Ability所在应用的包名以及对应包内的Ability名称。当UIAbilityA启动UIAbilityB并需要传入一些数据给UIAbilityB时,Want可以作为一个载体将数据传给UIAbilityB。

二、Want的类型

1、显式Want

在启动Ability时指定了abilityName和bundleName的Want称为显式Want。
当有明确处理请求的对象时,通过提供目标Ability所在应用的包名信息(bundleName),并在Want内指定abilityName便可启动目标Ability。显式Want通常用于在当前应用开发中启动某个已知的Ability。

let wantInfo = {deviceId: '', // deviceId为空表示本设备bundleName: 'com.example.myapplication',abilityName: 'FuncAbility',
}

在这里插入图片描述

2、隐式Want

当请求处理的对象不明确时,希望在当前应用中使用其他应用提供的某个能力(通过​​skills标签​​定义),而不关心提供该能力的具体应用,可以使用隐式Want。例如使用隐式Want描述需要打开一个链接的请求,而不关心通过具体哪个应用打开,系统将匹配声明支持该请求的所有应用。

3、隐式Want的匹配

根据系统中待匹配Ability的匹配情况不同,使用隐式Want启动Ability时会出现以下三种情况。

  • 未匹配到满足条件的Ability:启动失败。
  • 匹配到一个满足条件的Ability:直接启动该Ability。
  • 匹配到多个满足条件的Ability(UIAbility):弹出选择框让用户选择。

匹配约束:

  • 调用方传入的want参数中不带有abilityName和bundleName,则不允许通过隐式Want启动所有应用的ServiceExtensionAbility。
  • 调用方传入的want参数中带有bundleName,则允许使用startServiceExtensionAbility()方法隐式Want启动ServiceExtensionAbility,默认返回优先级最高的ServiceExtensionAbility,如果优先级相同,返回第一个。
  let wantInfo: Want = {deviceId: "",action: "ohos.want.action.viewData",entities: ['entity.system.videoPlayer'],abilityName: "",uri: "",type: "",parameters: {}}

在这里插入图片描述

通过上面表格可以除了bundleName和moduleName,只有uri、type、action、entities 字段参与匹配,换句话说提供相应能力的hap中的moudle.json5 里的skills 的这四个字段的值会影响到匹配结果。
在这里插入图片描述

三、隐式启动Want 源码概述

foundation/ability/ability_runtime/services/abilitymgr/src/implicit_start_processor.cpp 处理隐式匹配规则
foundation/ability/ability_runtime/services/abilitymgr/src/system_dialog_scheduler.cpp 弹出模态对话框

1、有且仅有一个Ability匹配

在这里插入图片描述

2、有多个Ability 匹配需要弹出选择对话框

在这里插入图片描述

3、ImplicitStartProcessor::ImplicitStartAbility

对应的代码由ImplicitStartProcessor::ImplicitStartAbility开始处理,首先AbilityRequest的callType = 0,传入的DeviceType为tablet,而社区默认是default。

3.1、GenerateAbilityRequestByAction

传入std::vector dialogAppInfos、deviceType 成功创建AbilityRequest对象,

3.1.1、GetBundleManagerHelper 获取BMS对象
3.1.2、GetBundleManagerHelper()->ImplicitQueryInfos
3.1.3、ImplicitStartProcessor::FilterAbilityList
3.2、定义回调
auto startAbilityTask = [imp = shared_from_this(), request, userId, identity](const std::string& bundle, const std::string& abilityName) mutable {HILOG_INFO("implicit start ability call back.");IPCSkeleton::SetCallingIdentity(identity);AAFwk::Want targetWant = request.want;targetWant.SetElementName(bundle, abilityName);auto callBack = [imp, targetWant, request, userId]() -> int32_t {return imp->ImplicitStartAbilityInner(targetWant, request, userId);};return imp->CallStartAbilityInner(userId, targetWant, callBack, request.callType);
};
3.3、根据dialogAppInfos和deviceType的组合进行不同的分支处理
  • dialogAppInfos.size() == 0 && (deviceType == STR_PHONE || deviceType == STR_DEFAULT

  • dialogAppInfos.size() == 0 && deviceType != STR_PHONE && deviceType != STR_DEFAULT

  • dialogAppInfos.size() == 0 && deviceType != STR_PHONE && deviceType != STR_DEFAULT

  • deviceType == STR_PHONE || deviceType == STR_DEFAULT
    DelayedSingleton::GetInstance()->GetSelectorDialogWant(dialogAppInfos, request.want, request.callerToken)

以上四种情况之外的

4、当有多个匹配结果时会先执行FilterAbilityList(有条件执行)

  • MatchTypeAndUri
  • AddAbilityInfoToDialogInfos
  • 循环从extensionInfos中获取dialogAppInfo信息并存入dialogAppInfos
    在这里插入图片描述

小结

弹出对话框的SelectorDialog_Service是一个ServiceExtensionAbility,进程为com.ohos.amsdialog,连接上Selector_Dialog_Service后会触发其onCreate->OnRequest函数执行,createWindow时
在这里插入图片描述

  private async createWindow(name: string, windowType: number, rect) {let deviceTypeInfo = deviceInfo.deviceType;console.info(TAG, 'create window');try {win = await window.create(globalThis.selectExtensionContext, name, windowType);if (windowType === window.WindowType.TYPE_DIALOG) {await win.bindDialogTarget(globalThis.callerToken.value, () => {win.destroyWindow();winNum--;if (winNum === 0) {globalThis.selectExtensionContext.terminateSelf();}});}if (deviceTypeInfo !== 'default') {await win.hideNonSystemFloatingWindows(true);}await win.moveTo(rect.left, rect.top);await win.resetSize(rect.width, rect.height);if (globalThis.params.deviceType === 'phone' || globalThis.params.deviceType === 'tablet') {await win.loadContent('pages/selectorPhoneDialog');} else {await win.loadContent('pages/selectorPcDialog');}await win.setBackgroundColor('#00000000');await win.show();} catch (e) {console.error(TAG, 'window create failed: ' + JSON.stringify(e));}}

然后去触发方舟编译器解包ams_system_dialog.hap执行,
在这里插入图片描述
最终结论:
1、win.hideNonSystemFloatingWindows(true); 的父类实现中默认报异常中断,所以需要在子类中实现该函数。(但是问题来了,里面的细节如何实现呢?社区中都是直接返回true)
2、在不同的设备上弹出的匹配对话框的位置和尺寸大小还需要适配,在
this.createWindow(‘SelectorDialog’ + startId, windowType, navigationBarRect);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/906628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Rules and Monetization

The system creates rules that allow them to monetize. The system doesn’t just enforce rules — it creates them strategically to monetize control. 🔧 How It Works: Invent a rule (e.g., “You need a permit to sell food.”)Claim it’s for safety …

java中string类型的list集合放到redis的5种数据类型的那种比较合适呢,可以用StringRedisTemplate实现

在Java中,如何将一个String类型的List集合存储到Redis中,并且应该选择Redis的哪种数据类型。同时,用户还问到是否可以使用StringRedisTemplate来实现。 首先,我需要回忆一下Redis的5种主要数据类型:字符串(…

基于DQN的学习资源难度匹配智能体

基于DQN的学习资源难度匹配智能体 下面我将实现一个基于DQN(深度Q网络)的智能体,用于根据用户的学习表现动态匹配适合难度的学习资源。这个系统可以应用于在线教育平台,根据用户的历史表现自动调整推荐资源的难度级别。 1. 环境设置 首先我们需要定义学习环境,这里我创建…

OrangePi Zero2开发指南:从SDK获取到交叉编译全流程详解

一、OrangePi Zero2 SDK说明 SDK 全称 Software Development Kit,即软件开发工具包。一般包括了一些工具(如交叉编译工具链)、库、文档和示例代码。香橙派的Linux SDK其实指的就是 orangepi-build 这套代码集,orangepibuild 在脚…

MATLAB NLP 工具箱 文本预处理教程

文章目录 前言一、文本预处理核心步骤二、MATLAB 实现示例三、高级预处理技术四、预处理流程整合五、性能优化与注意事项六、实战案例:IMDB 影评预处理 前言 以下是 MATLAB 自然语言处理 (NLP) 工具箱的文本预处理教程,涵盖核心步骤、代码实现及最佳实践…

大模型的量化与双重量化(1)

文章目录 大模型量化的含义和作用什么是量化量化的作用具体示例 双重量化的含义和作用什么是双重量化双重量化的具体实现双重量化的作用具体示例对比实际应用场景 大模型量化的含义和作用 什么是量化 量化是指将神经网络中的参数(权重和激活值)从高精度…

ES6 新增 API 方法

ES6 新增 API 方法 目录 ES6 新增 API 方法背景介绍数组方法1. Array.from()2. Array.of()3. find/findIndex4. includes5. flat/flatMap 对象方法1. Object.assign()2. Object.keys/values/entries3. Object.getOwnPropertyDescriptors() 字符串方法1. includes/startsWith/en…

vscode使用ssh链接服务器

vscode SSH vscode先下载remote ssh的插件,随后在左边的菜单栏里选择远程。 点击新建连接,输入用户名和地址,-p参数指定端口 ssh ubuntu{ip} -p xxx 随后就可以正常连接了,这里使用普通用户的用户名密码,别用root。 配…

基于FPGA的电子万年历系统开发,包含各模块testbench

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于FPGA的电子万年历系统开发,包含各模块testbench。主要包含以下核心模块: 时钟控制模块:提供系统基准时钟和计时功能。 日历计算模块&#xff1a…

C++ 的 out_ptr 和 inout_ptr

1 问题的起因 1.1 T** 或 T&* ​ C 的智能指针可以通过 get() 和 * 的重载得到原始指针 T*&#xff0c;遇到这样的 C 风格的函数的时候&#xff1a; void Process(Foo *ptr);std::unique_ptr<Foo> sp ...;Process(sp.get()); //调用 Process 函数Process() 函数以…

取消 Conda 默认进入 Base 环境

在安装 Conda 后&#xff0c;每次打开终端时默认会进入 base 环境。可以通过以下方法取消这一默认设置。 方法一&#xff1a;使用命令行修改配置 在终端中输入以下命令&#xff0c;将 auto_activate_base 参数设置为 false&#xff1a; conda config --set auto_activate_ba…

数字计数--数位dp

1.不考虑前导零 2.每一位计数&#xff0c;就是有点“数页码”的意思 P2602 [ZJOI2010] 数字计数 - 洛谷 相关题目&#xff1a;记得加上前导零 数页码--数位dp-CSDN博客 https://blog.csdn.net/2301_80422662/article/details/148160086?spm1011.2124.3001.6209 #include…

Redis学习打卡-Day5-Redis 持久化

单点 Redis 的一些问题 数据丢失&#xff1a;Redis 是内存存储&#xff0c;服务重启可能会丢失数据。solution&#xff1a;实现 Redis 数据持久化。并发能力&#xff1a;单节点 Redis 并发能力虽然不错&#xff0c;但也无法满足如618这样的高并发场景。solution&#xff1a;搭…

飞书知识问答深度体验:企业AI应用落地的典范产品

飞书知识问答深度体验&#xff1a;企业AI应用落地的典范产品 产品介绍-飞书知识问答是什么与常规通用大模型相比有何优点&#xff1f;大模型横行的时代&#xff0c;飞书知识问答对普通人和企业有何影响呢&#xff1f; 场景示例-不同角色可以用飞书知识问答做什么&#xff1f;对…

Python打卡训练营学习记录Day34

知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数 GPU性能的查看&#xff1a;看显存、看级别、看架构代际 GPU训练的方法&#xff1a;数据和模型移动到GPU device上 类的call方法&#xff1a;为什么定义前向传播时可以直接写作self.fc1(x) CPU性…

Django的请求和响应+template模板

&#x1f31f; 如果这篇文章触动了你的心弦&#xff0c;请不要吝啬你的支持&#xff01; 亲爱的读者&#xff0c; 感谢你花时间阅读这篇分享。希望这里的每一个字都能为你带来启发或是让你会心一笑。如果你觉得这篇文章有价值&#xff0c;或者它解决了你一直以来的一个疑问&a…

Python |GIF 解析与构建(2):状态机解析

Python &#xff5c;GIF 解析与构建&#xff08;2&#xff09;&#xff1a;状态机解析 目录 Python &#xff5c;GIF 解析与构建&#xff08;2&#xff09;&#xff1a;状态机解析 引言 一、状态机概述 状态机的优势与改进方向 总结 引言 在《Python &#xff5c;GIF 解…

PCB设计实践(二十六)贴片电容与插件电容的全面解析:差异、演进与应用场景

一、核心差异&#xff1a;结构与性能对比 物理结构与封装形式 贴片电容&#xff08;Surface Mount Device, SMD&#xff09;采用扁平化设计&#xff0c;外形多为长方体或圆柱体&#xff0c;直接通过焊盘固定在电路板表面。其封装材料通常为陶瓷、聚合物或铝电解层&#xff0c;外…

XC7A200T-2FFG1156I FPGA AMD Xilinx Artix-7

XC7A200T-2FFG1156I 是 AMD Xilinx Artix-7 系列的一款高性能低功耗 FPGA&#xff0c;采用 28 nm 高性能低功耗&#xff08;HPL&#xff09;工艺制造&#xff0c;核心电压在 0.95 V–1.05 V 之间&#xff0c;可在 –40 C 至 100 C 工业温度范围内稳定工作 。 逻辑资源&#xff…

LVS + Keepalived + Nginx 高可用负载均衡系统实验

1. 项目背景 在现代 Web 应用中&#xff0c;高可用性和负载均衡是至关重要的需求。本项目旨在通过 LVS&#xff08;Linux Virtual Server&#xff09;实现流量分发&#xff0c;通过 Keepalived 实现高可用性&#xff0c;通过 Nginx 提供后端服务。该架构能够确保在单点故障的情…