鸿蒙开发——进程模型与进程通信

news2024/11/26 12:18:27

1、进程模型

❓ 什么是进程?

进程是一个正在执行的程序的实例。当我们启动一个程序时,操作系统会创建一个进程,分配给它所需的资源,如内存和CPU时间。每个进程至少有一个线程,即执行线程,负责执行程序的指令。进程是操作系统进行资源分配和调度的基本单位,是操作系统提供给用户和应用程序的一个抽象概念。

在鸿蒙的进程模型中,进程被分为三类:主进程(负责UI的进程)、扩展进程(负责大部分ExtensionAbility)、WebView渲染进程(负责网页渲染的独立进程)。

  • 主进程

应用中(同一Bundle名称)的所有UIAbility、ServiceExtensionAbility和DataShareExtensionAbility均是运行在同一个独立进程(主进程)中,如下图中绿色部分的“Main Process”。

仅系统应用支持构建ServiceExtensionAbility和DataShareExtensionAbility
  • 扩展进程(可能有多个)

应用中(同一Bundle名称)的所有同一类型ExtensionAbility(除ServiceExtensionAbility、DataShareExtensionAbility外)均是运行在一个独立进程中,如下图中蓝色部分的“FormExtensionAbility Process”、“InputMethodExtensionAbility Process”、其他ExtensionAbility Process。

  • WebView进程

WebView拥有独立的渲染进程,如下图中黄色部分的“Render Process”。

图片

2、进程间通信方式

在鸿蒙开发中,需要跨进程通信的原因,是因为每个进程都有自己独立的资源和内存空间,其他进程不能随意访问不同进程的内存和资源。

进程间通信一般有两种方式:1)IPC/RPC;2)公共事件机制。

  • IPC/RPC

IPC(Inter-Process Communication): 使用Binder驱动,用于设备内的跨进程通信。

RPC(Remote Procedure Call):使用软总线驱动,用于跨设备跨进程通信。

由于篇幅原因,IPC和RPC在未来的文章中展开介绍
  • 公共事件机制

公共事件机制多用于一对多的通信场景(公共事件发布者可能存在多个订阅者同时接收事件)

基于鸿蒙的进程模型,针对应用间和应用内存在多个进程的情况,推荐使用公共事件机制来实现进程间通信。

3、公共事件机制

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

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

  • 系统公共事件:CES内部定义的公共事件,当前仅支持系统应用和系统服务发布,例如HAP安装、更新、卸载等公共事件(系统公共事件参考官方文档定义:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/commoneventmanager-definitions-V5 )

  • 自定义公共事件:应用定义的公共事件,可用于实现跨进程的事件通信能力。

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

  • 无序公共事件:CES在转发公共事件时,不考虑订阅者是否接收到该事件,也不保证订阅者接收到该事件的顺序与其订阅顺序一致。

  • 有序公共事件:CES在转发公共事件时,根据订阅者设置的优先级等级,优先将公共事件发送给优先级较高的订阅者,等待其成功接收该公共事件之后再将事件发送给优先级较低的订阅者。如果有多个订阅者具有相同的优先级,则他们将随机接收到公共事件。

  • 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。【普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请ohos.permission.COMMONEVENT_STICKY权限】

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

图片

3.1、发布公共事件

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

// 发布简单的公共事件publish(event: string, callback: AsyncCallback)// 指定发布信息并发布公共事件publish(event: string, options: CommonEventPublishData, callback: AsyncCallback)// CommonEventPublishData 结构定义如下:class CommonEventPublishData {// 表示订阅者包名称,只有包名为bundleName的订阅者才能收到该公共事件。bundleName: string// 表示公共事件的结果代码。code: number// 表示公共事件的自定义结果数据。data: string// 表示订阅者的权限。subscriberPermissions: Array<string>// 表示是否是有序事件。isOrdered: boolean// 表示是否是粘性事件。仅系统应用或系统服务允许发送粘性事件。isSticky: boolean// 表示公共事件的附加信息。parameters: {[key: string]: any}}

👉🏻 发布一个不携带信息的公共事件

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

// 1. 导入模块import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';import { promptAction } from '@kit.ArkUI';import { hilog } from '@kit.PerformanceAnalysisKit';const TAG: string = 'ProcessModel';const DOMAIN_NUMBER: number = 0xFF00;// ...// 2. 传入需要发布的事件名称和回调函数,发布事件。// 发布公共事件,其中的event字段需要替换为实际的事件名称。commonEventManager.publish('event', (err: BusinessError) => {  if (err) {    hilog.info(DOMAIN_NUMBER, TAG, `PublishCallBack err = ${JSON.stringify(err)}`);  } else {    //...    hilog.info(DOMAIN_NUMBER, TAG, `Publish success`);  }});

👉🏻 发布一个携带信息的公共事件

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

// 导入模块import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';import { hilog } from '@kit.PerformanceAnalysisKit';const TAG: string = 'ProcessModel';const DOMAIN_NUMBER: number = 0xFF00;// 2. 构建需要发布的公共事件信息。let options: commonEventManager.CommonEventPublishData = {  code: 1, // 公共事件的初始代码  data: 'initial data', // 公共事件的初始数据};// 3.传入需要发布的事件名称、需要发布的指定信息和回调函数,发布事件。// 发布公共事件,其中的event字段需要替换为实际的事件名称。commonEventManager.publish('event', options, (err: BusinessError) => {  if (err) {    hilog.error(DOMAIN_NUMBER, TAG, 'PublishCallBack err = ' + JSON.stringify(err));  } else {    //...    hilog.info(DOMAIN_NUMBER, TAG, 'Publish success');  }});

3.2、动态订阅公共事件

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

动态订阅公共事件的接口定义如下:​​​​​​​

// 创建订阅者对象(Callback和Promise版本)reateSubscriber(subscribeInfo: CommonEventSubscribeInfo, callback: AsyncCallback<CommonEventSubscriber>): voidcreateSubscriber(subscribeInfo: CommonEventSubscribeInfo): Promise<CommonEventSubscriber>// 订阅公共事件。subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback): void// CommonEventSubscribeInfo结构定义如下:class CommonEventSubscribeInfo {// 表示要订阅的公共事件。events: Array<string>// 表示发布者的权限,订阅方将只能接收到具有该权限的发送方发布的事件。publisherPermission: string// 表示设备ID,该值必须是同一ohos网络上的现有设备ID。通过@ohos.deviceInfo获取udid,作为订阅者的设备ID。publisherDeviceId: string// 表示用户ID。参数可选,默认值当前用户的ID。如果指定了此参数,则该值必须是系统中现有的用户ID。通过getOsAccountLocalId获取系统账号ID,作为订阅者的用户ID。userId: number// 表示订阅者的优先级。值的范围是-100到1000,超过上下限的优先级将被设置为上下限值。priority: number//表示要订阅的发布者的bundleName。publisherBundleName: string}

👉🏻 动态订阅示例代码如下:​​​​​​​

// 1. 导入模块import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';import { promptAction } from '@kit.ArkUI';import { hilog } from '@kit.PerformanceAnalysisKit';const TAG: string = 'ProcessModel';const DOMAIN_NUMBER: number = 0xFF00;// 2. 创建订阅者信息(结构详见上文中的CommonEventSubscribeInfo)// 用于保存创建成功的订阅者对象,后续使用其完成订阅及退订的动作let subscriber: commonEventManager.CommonEventSubscriber | null = null;// 订阅者信息,其中的event字段需要替换为实际的事件名称。let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {    events: ['event'], // 订阅灭屏公共事件};// 3.创建订阅者,保存返回的订阅者对象subscriber,用于执行后续的订阅、退订等操作。// 创建订阅者回调commonEventManager.createSubscriber(subscribeInfo, (err: BusinessError, data: commonEventManager.CommonEventSubscriber) => {  if (err) {    hilog.error(DOMAIN_NUMBER, TAG, `Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);    return;  }  hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in creating subscriber.');  subscriber = data;})//4. 创建订阅回调函数,订阅回调函数会在接收到事件时触发。订阅回调函数返回的data内包含了公共事件的名称、发布者携带的数据等信息// 订阅公共事件回调if (subscriber !== null) {  commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => {    if (err) {      hilog.error(DOMAIN_NUMBER, TAG, `Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);      return;    }    // ...  })} else {  hilog.error(DOMAIN_NUMBER, TAG, `Need create subscriber`);}

⭐️ 其中,订阅回调函数中CommonEventData数据结构定义如下:​​​​​​​

class CommonEventData {// 表示当前接收的公共事件名称。event: string// 表示包名称,当前默认为空。bundleName: string// 表示公共事件的结果代码,用于传递int类型的数据。code: number// 表示公共事件的自定义结果数据,用于传递string类型的数据。data: string// 表示公共事件的附加信息。parameters: {[key: string]: any}}

3.3、取消动态订阅公共事件

动态订阅者完成业务需要时,需要主动取消订阅,订阅者通过调用unsubscribe()方法取消订阅事件。接口定义如下:​​​​​​​

// 取消订阅公共事件unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback)

👉🏻 取消动态订阅公共事件示例如下:​​​​​​​

// 1. 导入模块import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';import { hilog } from '@kit.PerformanceAnalysisKit';const TAG: string = 'ProcessModel';const DOMAIN_NUMBER: number = 0xFF00;// 2. 根据3.2步骤中介绍的,订阅某个公共事件// 3. 调用CommonEvent中的unsubscribe()方法取消订阅某事件// subscriber为订阅事件时创建的订阅者对象if (this.subscriber !== null) {  commonEventManager.unsubscribe(this.subscriber, (err: BusinessError) => {    if (err) {      hilog.error(DOMAIN_NUMBER, TAG, `UnsubscribeCallBack err = ${JSON.stringify(err)}`);    } else {      hilog.info(DOMAIN_NUMBER, TAG, `Unsubscribe success`);      this.subscriber = null;    }  })}

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

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

相关文章

SQL server 中 CROSS APPLY的使用

CROSS APPLY 是 SQL Server 中的一个操作符&#xff0c;用于将一个表表达式&#xff08;如子查询、函数等&#xff09;与外部表进行连接。CROSS APPLY 类似于 INNER JOIN&#xff0c;但它允许你在一个查询中多次引用外部表的行&#xff0c;并且可以动态地生成结果集。 基本语法…

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…

[大模型]Diffusion扩散式生成模型

一、概述 扩散式生成模型相较于GAN网络的对抗式生成模型&#xff0c;有更高的精度&#xff0c;也更符合人类的视觉和审美罗技&#xff0c;且风格化能力更强。现行的所有Diffusion模型都是基于2020年的论文DDPM来实现的。 GAN网络通过使生成器(Generator)生成的模型尽可能的逼近…

十四届蓝桥杯STEMA考试Python真题试卷第二套第五题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…

keil5的Debug调试时,卡在 LDR R0, =SystemInit,无法往后进行

解决办法&#xff1a;使用STM32Cube生成的工程文件时&#xff0c;勾选Use MicroLIB即可

OpenEuler 使用ffmpeg x11grab捕获屏幕流,rtsp推流,并用vlc播放

环境准备 安装x11grab(用于捕获屏幕流)和libx264(用于编码) # 基础开发环境&x11grab sudo dnf install -y \autoconf \automake \bzip2 \bzip2-devel \cmake \freetype-devel \gcc \gcc-c \git \libtool \make \mercurial \pkgconfig \zlib-devel \libX11-devel \libXext…

ai常见实验

参考链接https://arxiv.org/pdf/2410.19894 对比实验&#xff08;sota 表格&#xff09; -辅助信息可以体现 P F 等 可视化结果 &#xff08;图片形式&#xff09; 消融实验 超参数实验 &#xff08;有时候表示 有时候单独表格 看哪个参数好&#xff09; 部分消融和超参数…

【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Oracle OCP认证考试考点详解082系列12

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 56. 第56题&#xff1a; 题目 解析及答案&#xff1a; 关于企业管理器&#xff08;EM&#xff09;Express&#xff0c;以下哪两个陈述是…

任务:拟合曲面

3d 要拟合粗的蓝色曲面&#xff0c;剩下三条线是在3个平面的投影 1 2 3 4d

Python世界:自动化办公Word之批量替换文本生成副本

Python世界&#xff1a;自动化办公Word之批量替换文本生成副本 任务背景编码思路代码实现相关参考 任务背景 为提高办公效率&#xff0c;用python试手了一个word任务&#xff0c;要求如下&#xff1a; 给你一个基础word文档A&#xff0c;格式为docx&#xff0c;名字为&#xf…

如何检查雷池社区版 WAF 是否安装成功?

容器运行状态检查&#xff1a; 使用命令行检查&#xff1a;打开终端&#xff0c;连接到安装雷池的服务器。运行 docker ps 命令&#xff0c;查看是否有与雷池相关的容器正在运行。 如果能看到类似 safeline-mgt、safeline-tengine 等相关容器&#xff0c;并且状态为 Up&#x…

青少年编程能力等级测评CPA Python编程(一级)

青少年编程能力等级测评CPA Python编程(一级) &#xff08;考试时间90分钟&#xff0c;满分100分&#xff09; 一、单项选择题&#xff08;共20题&#xff0c;每题3.5分&#xff0c;共70分&#xff09; 下列语句的输出结果是&#xff08; &#xff09;。 print(35*2) A&a…

java学习2

一、什么是方法 方法&#xff08;method&#xff09;是程序中最小的执行单元 重复的代码、具有独立功能的代码可以抽取到方法中&#xff1b;提高代码的复用性和可维护性。 二、方法的格式 1.方法的格式定义&#xff1a; 最简单的方法定义 调用&#xff1a;playGame(); 带…

蓝牙资讯|苹果AirPods Pro 2推出听力测试、助听器和听力保护等功能

苹果推送iOS 18.1 系统版本更新&#xff0c;AirPods Pro 2 用户也在 iOS 18.1 中获得了强大的新功能。 运行固件 7B19 的 AirPods Pro 2 用户&#xff0c;搭配 iOS 18.1 系统的 iPhone&#xff0c;将获得三项强大的听力健康功能&#xff1a;听力测试、助听器和听力保护。 听力…

【学习日记】Anaconda的安装与使用-小白大学生

目录 日记说明 解压安装&#xff1a; 配置 使用 日记说明 作者是个大学生 这个专栏主要收集课时常用的软件 以及女朋友上课用的软件的教程 所有安装包可以私聊我获取 免费 提前清除已有python环境 windows11 Anaconda-2024.02 垃圾话&#xff1a; Anaconda 是全球领先的数…

内网项目,maven本地仓库离线打包,解决Cannot access central in offline mode?

背景&#xff1a; 内网项目打包&#xff0c;解决Cannot access central in offline mode? 1、修改maven配置文件&#xff1a; localRepository改为本地仓库位置 <localRepository>D:\WorkSpace\WorkSoft\maven-repository\iwhalecloud-repository\business</loca…

教你怎样搭建自动化测试框架?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 最近好多小伙伴都在说接口自动化测试&#xff0c;那么究竟什么是接口自动化测试呢&#xff1f;让我们一起往下看就知道了&#xff0c;首先我们得先弄清楚下面这…

反转链表.

给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#xff1a; 输入&am…

数列分块入门

本期是数列分块入门。其中的大部分题目来自hzwer在LOJ上提供的数列分块入门系列。 Blog:here (其实是对之前分块的 blog 的整理补充) sto hzwer orz %%% [转载] ---------------------------------------------------------------------------------…