OpenHarmony实战开发—进程间通讯

版本:v3.2 Beta5

进程模型

OpenHarmony的进程模型如下图所示:

  • 应用中(同一包名)的所有UIAbility、ServiceExtensionAbility、DataShareExtensionAbility运行在同一个独立进程中,即图中绿色部分的“Main Process”。
  • 应用中(同一包名)的同一类型ExtensionAbility(除ServiceExtensionAbility和DataShareExtensionAbility外)运行在一个独立进程中,即图中蓝色部分的“FormExtensionAbility Process”、“InputMethodExtensionAbility Process”、其他ExtensionAbility Process。
  • WebView拥有独立的渲染进程,即图中黄色部分的“Render Process”。
    图1进程模型示意图

在上述模型基础上,对于系统应用可以通过申请多进程权限(如下图所示),为指定HAP配置一个自定义进程名,该HAP中的UIAbility、DataShareExtensionAbility、ServiceExtensionAbility就会运行在自定义进程中。不同的HAP可以通过配置不同的进程名运行在不同进程中。

图2 多进程示意图

基于OpenHarmony的进程模型,系统中应用间和应用内都会存在多个进程的情况,因此系统提供了如下两种进程间通信机制:

  • 公共事件机制:多用于一对多的通信场景,公共事件发布者可能存在多个订阅者同时接收事件。
  • 后台服务机制:当前主要通过ServiceExtensionAbility 的能力实现。

公共事件简介

OpenHarmony通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力。

公共事件从系统角度可分为:系统公共事件和自定义公共事件。

  • 系统公共事件:CES内部定义的公共事件,只有系统应用和系统服务才能发布,例如HAP安装,更新,卸载等公共事件。目前支持的系统公共事件详见 系统公共事件列表。
  • 自定义公共事件:应用自定义一些公共事件用来实现跨进程的事件通信能力。

公共事件按发送方式可分为:无序公共事件、有序公共事件和粘性公共事件。

  • 无序公共事件:CES转发公共事件时,不考虑订阅者是否接收到,且订阅者接收到的顺序与其订阅顺序无关。
  • 有序公共事件:CES转发公共事件时,根据订阅者设置的优先级等级,在接收到优先级较高的一个订阅者回复后,再向下一个优先级较低的订阅者转发公共事件。具有相同优先级的订阅者将按随机顺序收到公共事件。
  • 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请ohos.permission.COMMONEVENT_STICKY权限,配置方式请参见 访问控制授权申请。

每个应用都可以按需订阅公共事件,订阅成功,当公共事件发布时,系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。

图1 公共事件示意图

公共事件订阅概述

公共事件服务提供了动态订阅和静态订阅两种订阅方式。动态订阅与静态订阅最大的区别在于,动态订阅是应用运行时行为,而静态订阅是后台服务无需处于运行状态。

  • 动态订阅:指订阅方在运行时调用公共事件订阅的API实现对公共事件的订阅,详见 动态订阅公共事件 。
  • 静态订阅:订阅方通过配置文件声明和实现继承自StaticSubscriberExtensionAbility的类实现对公共事件的订阅,详见 静态订阅公共事件 。

动态订阅公共事件

场景介绍

动态订阅是指当应用在运行状态时对某个公共事件进行订阅,在运行期间如果有订阅的事件发布那么订阅了这个事件的应用将会收到该事件及其传递的参数。例如,某应用希望在其运行期间收到电量过低的事件,并根据该事件降低其运行功耗,那么该应用便可动态订阅电量过低事件,收到该事件后关闭一些非必要的任务来降低功耗。订阅部分系统公共事件需要先 申请权限 ,订阅这些事件所需要的权限请见 公共事件权限列表 。

接口说明

详细接口见 接口文档 。

开发步骤
  1. 导入CommonEvent模块。
import commonEvent from '@ohos.commonEventManager';
  1. 创建订阅者信息,详细的订阅者信息数据类型及包含的参数请见 CommonEventSubscribeInfo 文档介绍。
// 用于保存创建成功的订阅者对象,后续使用其完成订阅及退订的动作
let subscriber = null;
// 订阅者信息
let subscribeInfo = {events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
}
  1. 创建订阅者,保存返回的订阅者对象subscriber,用于执行后续的订阅、退订等操作。
// 创建订阅者回调
commonEvent.createSubscriber(subscribeInfo, (err, data) => {if (err) {console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`);} else {console.info(`[CommonEvent] CreateSubscriber success`);subscriber = data;// 订阅公共事件回调}
})
  1. 创建订阅回调函数,订阅回调函数会在接收到事件时触发。订阅回调函数返回的data内包含了公共事件的名称、发布者携带的数据等信息,公共事件数据的详细参数和数据类型请见 CommonEventData 文档介绍。
// 订阅公共事件回调
if (subscriber !== null) {commonEvent.subscribe(subscriber, (err, data) => {if (err) {console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`);} else {console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`);}})
} else {console.error(`[CommonEvent] Need create subscriber`);
}

静态订阅公共事件(仅对系统应用开放)

场景介绍

静态订阅者在未接收订阅的目标事件时,处于未拉起状态,当系统或应用发布了指定的公共事件后,静态订阅者将被拉起,并执行onReceiveEvent回调,开发者可通过在onReceiveEvent回调中执行业务逻辑,实现当应用接收到特定公共事件时执行业务逻辑的目的。例如,某应用希望在设备开机的时候执行一些初始化任务,那么该应用可以静态订阅开机事件,在收到开机事件后会拉起该应用,然后执行初始化任务。静态订阅是通过配置文件声明和实现继承自StaticSubscriberExtensionAbility的类实现对公共事件的订阅。需要注意的是,静态订阅公共事件对系统功耗有一定影响,建议谨慎使用

开发步骤
  1. 静态订阅者声明
    声明一个静态订阅者,首先需要在工程中新建一个ExtensionAbility, 该ExtensionAbility从StaticSubscriberExtensionAbility派生,其代码实现如下:
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'export default class StaticSubscriber extends StaticSubscriberExtensionAbility {onReceiveEvent(event) {console.log('onReceiveEvent, event:' + event.event);}
}

开发者可以在onReceiveEvent中实现业务逻辑。

  1. 静态订阅者工程配置
    在完成静态订阅者的代码实现后,需要将该订阅者配置到系统的module.json5中,配置形式如下:
{"module": {......"extensionAbilities": [{"name": "StaticSubscriber","srcEntrance": "./ets/StaticSubscriber/StaticSubscriber.ts","description": "$string:StaticSubscriber_desc","icon": "$media:icon","label": "$string:StaticSubscriber_label","type": "staticSubscriber","visible": true,"metadata": [{"name": "ohos.extension.staticSubscriber","resource": "$profile:subscribe"}]}]......}
}

上述json文件主要关注以下字段:

  • srcEntrance : 表示ExtensionAbility的入口文件路径,即步骤2中声明的静态订阅者所在的文件路径
  • type: 表示ExtensionAbility的类型,对于静态订阅者需要声明为“staticSubscriber”
  • metadata: 表示ExtensionAbility的二级配置文件信息。由于不同的ExtensionAbility类型其配置信息不尽相同,因此需要使用不同的config文件表示其具体配置信息。

○  name:表示ExtensionAbility的类型名称,对于静态订阅类型,name必须声明为“ohos.extension.staticSubscriber”,否则无法识别为静态订阅者;

○  resource: 字段表示ExtensionAbility的配置信息路径,由开发者自行定义,在本例中表示路径为“resources/base/profile/subscribe.json"。

metadata指向的二级配置文件的通常形式如下:

{"commonEvents": [{"name": "xxx","permission": "xxx","events":["xxx"]}]
}

需要注意二级配置文件必须按照此形式进行声明,否则会无法正确识别。下面对字段进行介绍:

  • name: 静态订阅ExtensionAbility的名称,需要和module.json5中声明的ExtensionAbility的name一致
  • permission:订阅者要求的发布者需要具备的权限,对于发布了目标事件但不具备permission中声明的权限的发布者将被视为非法事件不予发布
  • events: 订阅的目标事件列表
  1. 修改设备系统配置文件
    修改设备系统配置文件**/etc/static_subscriber_config.json**,将静态订阅应用者的包名添加至该json文件中即可。
{"xxx","ohos.extension.staticSubscriber","xxx"
}
相关示例

针对StaticSubscriberExtensionAbility开发,可参考如下实例:StaticSubscriber:静态订阅(ArkTS)(API9)(Full SDK)

取消动态订阅公共事件

场景介绍

动态订阅者完成业务需要时,需要主动取消订阅,订阅者通过调用 unsubscribe() 方法取消订阅事件。

接口说明

开发步骤
  1. 导入CommonEvent模块。
import commonEvent from '@ohos.commonEventManager';
  1. 根据 动态订阅公共事件 章节的步骤来订阅某个事件。
  2. 调用CommonEvent中的unsubscribe方法取消订阅某事件。
// subscriber为订阅事件时创建的订阅者对象
if (subscriber !== null) {commonEvent.unsubscribe(subscriber, (err) => {if (err) {console.error(`[CommonEvent] UnsubscribeCallBack err=${JSON.stringify(err)}`)} else {console.info(`[CommonEvent] Unsubscribe`)subscriber = null}})
}

公共事件发布

场景介绍

当需要发布某个自定义公共事件时,可以通过publish()方法发布事件。发布的公共事件可以携带数据,供订阅者解析并进行下一步处理。

须知: 已发出的粘性公共事件后来订阅者也可以接收到,其他公共事件都需要先订阅再接收,订阅参考公共事件订阅章节。

接口说明

详细接口见 接口文档 。

发布不携带信息的公共事件

不携带信息的公共事件,只能发布无序公共事件。

  1. 导入CommonEvent模块。
import commonEvent from '@ohos.commonEventManager';
  1. 传入需要发布的事件名称和回调函数,发布事件。
// 发布公共事件
commonEvent.publish("usual.event.SCREEN_OFF", (err) => {if (err) {console.error(`[CommonEvent] PublishCallBack err=${JSON.stringify(err)}`);} else {console.info(`[CommonEvent] Publish success`);}
})
发布携带信息的公共事件

携带信息的公共事件,可以发布为无序公共事件、有序公共事件和粘性事件,可以通过参数CommonEventPublishData的isOrdered、isSticky的字段进行设置。

  1. 导入CommonEvent模块。
import commonEvent from '@ohos.commonEventManager';ts
  1. 传入需要发布的事件名称和回调函数,发布事件。
// 公共事件相关信息
let options = {code: 1, // 公共事件的初始代码data: "initial data", // 公共事件的初始数据
}
  1. 传入需要发布的事件名称、需要发布的指定信息和回调函数,发布事件。
// 发布公共事件
commonEvent.publish("usual.event.SCREEN_OFF", options, (err) => {if (err) {console.error('[CommonEvent] PublishCallBack err=' + JSON.stringify(err));} else {console.info('[CommonEvent] Publish success')}
})

后台服务

Stage模型提供了ServiceExtensionAbility来提供后台服务的能力,支持系统应用实现一个后台服务并对外提供相应的能力;系统应用A实现了一个后台服务,三方应用B可以通过连接系统应用A的后台服务与其进行进程间通信。

ServiceExtensionAbility的详细介绍请参见 后台服务开发指导 。

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:https://gitee.com/MNxiaona/733GH

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

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

相关文章

进口透明可视耐腐蚀PFA进样管特氟龙圆底试管适配MC-ICP-MS

PFA进样管可适配Neptune plus多接收器等离子质谱仪(MC-ICP-MS),广泛应用于地球化学、核保障、环境科学、金属组学领域,在生物、物理、化学、材料等多个学科的交叉方向也有良好的应用前景。 外观半透明,便于观察管内情…

.BEAST勒索病毒肆虐:企业和个人如何应对数据加密威胁?

1. .BEAST勒索病毒的介绍: .BEAST勒索病毒是一种恶意软件,它利用加密算法对用户的文件进行加密,并索要赎金以换取解密密钥。如果您的数据承载着企业机密、客户信赖与研发心血,欢迎添加技术服务号(safe130)以…

uniapp 引用组件后 不起作用 无效果 不显示

根据uniapp官方文档easycom组件规范 只要组件安装在项目的components目录下或uni_modules目录下,并符合components/组件名称/组件名称.(vue|uvue)目录结构(注意:当同时存在vue和uvue时,uni-app 项目优先使用 vue 文件,…

ZABBIX API:高效监控的利器

新钛云服已累计为您分享794篇技术干货 ZABBIX是一款广受欢迎的高效监控工具,它提供了一系列丰富的API接口,使得日常监控任务变得更加便捷。无论是查看信息、添加主机、应用监控模板,还是执行删除操作,ZABBIX API都能助您一臂之力&…

信号带宽和上升沿时间

我们在抽取高速信号的S参数时避不开的一个环节是设置仿真带宽,经常听到有人讲要设置基频(奈奎斯特频率)的4倍or 5倍带宽,如果是这样,就有一个问题:如果是56Gbps的NRZ信号,那仿真带宽真要设置到1…

linux系统-深入学习文件系统与日志分析

目录 一、inode于block inode于block概括inode的内容inode包含文件的元信息用stat命令可以查看某个文件的inode信息Linux系统文件三个主要的时间属性目录文件架构 用户通过文件名打开文件时,系统内部的过程查看inode号码的实操硬盘分区后的结构 👇用户访…

【golang学习之旅】Go 的基本数据类型

系列文章 【golang学习之旅】报错:a declared but not used 目录 系列文章总览布尔型(bool)字符串型(string)整数型(int、uint、byte、rune)浮点型(float32、float64)复…

【我的Java学习笔记-3】

运算符和表达式 运算符: 对字面量或者变量进行操作的符号。 表达式: 用运算符把字面量或者变量连接起来符合java语法的式子就可以称为表达式。不同运算符连接的表达式体现的是不同类型的表达式。 举例说明: int a10; int b 20; int c a b; …

软件测试报告的用途

软件测试报告的用途十分广泛,主要体现在以下几个方面: 评估软件质量:软件测试报告是对软件进行全面、系统测试后的总结,通过报告中的各项数据和结果,可以评估软件的质量水平,包括功能的完整性、性能的稳定…

linux-进程(2)

1.通过系统调用获取进程标示符 进程id(PID) 父进程id(PPID) 每一个可执行程序运行起来之后都会成为一个进程,每个进程都有一个自己的id,以及一个父进程id,父进程就是创建自己进程的进程&#xf…

SCI一区级 | Matlab实现BES-CNN-GRU-Mutilhead-Attention多变量时间序列预测

SCI一区级 | Matlab实现BES-CNN-GRU-Mutilhead-Attention秃鹰算法优化卷积门控循环单元融合多头注意力机制多变量时间序列预测 目录 SCI一区级 | Matlab实现BES-CNN-GRU-Mutilhead-Attention秃鹰算法优化卷积门控循环单元融合多头注意力机制多变量时间序列预测预测效果基本介绍…

二叉树-从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]前序遍历的…