OpenHarmony实战开发—进程间通讯

news2024/12/28 20:18:52

版本: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.coloradmin.cn/o/1626904.html

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

相关文章

leaftjs+turfjs+idw纯前端实现等值面绘图+九段线

最近有个绘制等值面图的需求。我们一般的实现路径是: 1.后台绘图,用surfer绘制好,给前端调用叠加到地图。 2.后台用python绘图,绘制好给前端调用,叠加到地图。 3.后台进行插值计算、地图裁剪、最终生成geojson文件或…

电商技术揭秘三十四:智能风控业务架构浅析

相关系列文章 电商技术揭秘相关系列文章合集(1) 电商技术揭秘相关系列文章合集(2) 电商技术揭秘二十八:安全与合规性保障 电商技术揭秘二十九:电商法律合规浅析 电商技术揭秘三十:知识产权保…

vue 3 —— 笔记(模板语法,响应式变量)

模板语法: Vue 使用一种基于 html 的模板语法,使我们能声明式将其组件实例绑定到呈现的 dom 上 文本插值 基础数据绑定形式 双大括号 会替换相应组件实例 msg 属性的值 原始html 双大括号会将数据解释为纯文本 不是html 想插入html 使用 v-html 指令 &…

短距离无线通信-Zigbee

阅读引言: 最近在复习之前做过的项目, 所以向将zigbee这个协议分享出来, 一方面可以给需要的人看到, 一方面也方便自己整理zigbee的知识。 目录 一、什么是 ZigBee? 二、Zigbee 通信频段和信道 三、Zigbee协议和Zigbee协议栈 …

ATFX汇市:日本央行并未连续加息,日元剧烈贬值

ATFX汇市:今日11:22,日本央行公布4月利率决议结果,宣布维持0~0.1%的基准利率不变。日元应声贬值,三十分钟内,USDJPY从155.42猛涨至155.89,涨幅47基点。今日14:30,日本央行行长植田和男召开货币政…

类与对象(四)

目录 1.构造函数 1.1初始化列表 1.2 隐式类型转换 2.静态成员 2.1 静态成员变量 2.2静态成员函数 3.友元 3.1 友元函数 3.2 友元类 4.内部类 5.匿名对象 6.拷贝对象时的一些编译器优化 1.构造函数 1.1初始化列表 我们在将构造函数的时候讲过构造函数是对一个对象整体的…

HarmonyOS ArkUI实战开发-NAPI方法扩展

在前 3 小结笔者简单介绍了 NAPI 工程并对生成的源码进行了简单介绍,本节笔者在前 3 小节的基础上对 NAPI 工程做个扩展,再额外添加一个计算 MD5 的方法 md5()。 声明md5方法 在 index.d.ts 文件中声明一个 md5() 方法,该方法接收一个 stri…

自己搭建的大疆无人机RTMP流媒体服务延迟太大

流程:无人机摄像头->图传->遥控器->流媒体服务器->取流播放,延迟有10秒来的,大家有没有什么好的方案。

思考(1)

思考: 1. windows登录的明文密码,存储过程是怎么样的,密文存在哪个文件下,该文件是否可以打开,并且查看到密文 Windows登录的明文密码:是通过LSA(Local Security Authority)进行存储…

用过最佳的wordpress模板

西瓜红,作为一种充满活力和激情的颜色,总是能给人留下深刻的印象。当这种鲜艳的色彩与经典的设计元素相结合时,就能打造出一款既时尚又实用的WordPress企业模板。今天,我们向您隆重推荐这款西瓜红经典配色WordPress企业模板。 这…

HTML批量文件上传方案——图像预览方式

作者:私语茶馆 1.HTML多文件上传的关键方案 多文件上传包括:文件有效性校验,文件预览、存储和进度展示多个方面,本章节介绍的是文件预览的实现方案。 2.文件上传前预览 2.1.效果 选择文件前: 选择文件后: 2.2.CSS文件代码 StorageCenter.css代码 html {font-family:…

计算机组成原理实验(一)--可控加减法电路设计实验

一、一位全加器的设计 视频学习链接:3-2-4 定点数的加法和减法运算 — 一位全加器的硬件逻辑实现_哔哩哔哩_bilibili 仿真电路图: 总结:奇数个1时Si输出为1,偶数个1输出为0;1的个数大于等于2时,Ci输出1 实…

NEMU模拟器源码编译与使用

NEMU模拟器源码编译与使用 1 NEMU介绍2 NEMU编译3 NEMU使用3.1 下载MySBIBenOS3.2 使用riscv64-benos_defconfig编译NEMU3.3 编译MySBIBenOS3.4 运行MySBIBenOS 4 解决NEMU编译报错4.1 找不到readline/readline.h4.2 找不到path_manager.h 1 NEMU介绍 NEMU(NJU Emu…

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(三)KV缓存

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(三) KV缓存 在推理的每一步中,只对模型输出的最后一个标记感兴趣,因为已经有了之前的标记。然而,模型需要访问所有先前的标记来决定输出哪个标记&…

Redis入门到实战教程(基础篇)笔记

教学来源: Redis课程介绍导学_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1cr4y1671t?p1一、Redis 入门 1.认识NoSQL 2.Redis在虚拟机中的安装和开机自启 Redis在虚拟机中安装和配置开机自启-CSDN博客https://blog.csdn.net/qq_69183322/article/deta…

力扣37题:回溯算法之解数独

编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 数独部分空…

每日一题(力扣45):跳跃游戏2--贪心

由于题目已经告诉了我们一定可以跳到,所以我们只需去考虑前进最快的方法。即 判断当前下一步能跳的各个位置中,哪个能带你去去向最远的地方(why? 因为其他位置所能提供的最大范围都没最远那个大,所以最远的那个已经可以…

【元启发式算法】学生心理学优化算法 SPBO算法【Matlab代码#88】

文章目录 【获取资源请见文章第4节:资源获取】1. 学生心理学优化算法(SPBO)1.1 最好的学生1.2 次好的学生1.3 一般的学生1.4 随机提高成绩的学生 2. 部分代码展示3. 仿真结果展示4. 资源获取说明 【获取资源请见文章第4节:资源获取…

VTK----VTK数据结构详解3(代码篇)

上篇文章(VTK----VTK数据结构详解(计算机篇)-CSDN博客)从计算机数据结构(数组、链表等)的角度对数据数组、数据对象、数据属性的实现原理进行了说明,下面从代码的层面详细说明它们的使用及相关实…

【Leetcode笔记】501.二叉搜索树中的众数

文章目录 题目要求ACM 模式代码知识点 题目要求 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 …