【愚公系列】2023年12月 HarmonyOS教学课程 052-Stage模型(进程模型)
🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2023年华为云十佳博主,2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
🚀前言
进程是计算机中运行的程序的实例。它是操作系统对正在执行的程序的一种抽象概念。每个进程都有自己的独立内存空间、运行状态和执行上下文。进程可以包含一个或多个线程,每个线程可以独立执行一部分任务。操作系统通过分配和管理进程资源来实现多任务和并发执行。进程之间可以通过进程间通信机制进行数据交换和协作。
🚀一、进程模型
🔎1.概述
在HarmonyOS中,应用的进程模型是基于多线程的。每个应用会运行在一个独立的进程中,并且应用中的所有UIAbility(即应用的界面部分)会运行在同一个进程中。这意味着应用中的不同界面之间可以通过共享内存和消息传递等方式进行通信。
另外,HarmonyOS中的WebView拥有独立的渲染进程。这是为了提高浏览器的安全性和稳定性。通过将WebView的渲染过程与应用的进程隔离开来,避免了恶意网页对应用进行攻击或造成应用崩溃的情况。
HarmonyOS的进程模型是基于多线程的,应用的界面部分运行在同一个进程中,而WebView拥有独立的渲染进程。这样可以提高应用的安全性和稳定性。
🚀二、公共事件简介
🔎1.概述
HarmonyOS的公共事件服务(Common Event Service,CES)是一种机制,可以为应用程序提供订阅、发布和退订公共事件的能力。这个服务使得不同应用程序之间可以进行事件的交互和通信。
通过CES,应用程序可以定义自己的事件,并将这些事件发布到系统的事件总线上。其他应用程序可以通过订阅感兴趣的事件来接收相关的通知。当有事件发生时,发布者会将事件信息发送到事件总线,然后事件总线会将这些信息传递给所有订阅者。
CES提供了一种可靠的事件通信机制,可以在不同的应用程序之间进行事件的交互。这样,应用程序可以更方便地实现功能的集成和扩展。
在CES中,事件是以消息的形式进行传递的,可以包含任意类型的数据。应用程序可以根据需要定义不同类型的事件,并指定事件的触发条件和处理方式。
公共事件从系统角度可分为:系统公共事件和自定义公共事件
类型 | 描述 | 示例 |
---|---|---|
系统公共事件 | CES内部定义的公共事件,只有系统应用和系统服务才能发布 | HAP安装、更新、卸载等 |
自定义公共事件 | 应用自定义一些公共事件用来实现跨进程的事件通信能力 | 应用间数据传递、状态更新等 |
公共事件按发送方式可分为:无序公共事件、有序公共事件和粘性公共事件
类型 | 描述 |
---|---|
无序公共事件 | CES转发公共事件时,不考虑订阅者是否接收到,且订阅者接收到的顺序与其订阅顺序无关。 |
有序公共事件 | CES转发公共事件时,根据订阅者设置的优先级等级,优先将公共事件发送给优先级较高的订阅者,等待其成功接收该公共事件之后再将事件发送给优先级较低的订阅者。如果有多个订阅者具有相同的优先级,则他们将随机接收到公共事件。 |
粘性公共事件 | 能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅。发送粘性事件必须是系统应用或系统服务,且需要申请ohos.permission.COMMONEVENT_STICKY权限,配置方式请参阅访问控制授权申请指导。 |
🔎2.订阅
订阅是指在发布者-订阅者模式中,订阅者向发布者注册,以接收发布者发送的消息或事件。订阅者可以选择订阅他们感兴趣的特定主题或类型的消息。
在发布订阅模式中,订阅者需要执行以下步骤来进行订阅:
- 创建一个订阅者对象或函数,用于处理接收到的消息或事件。
- 向发布者注册订阅者。这通常通过调用发布者的订阅方法,并传递订阅者对象或函数作为参数来完成。订阅方法可能会要求提供订阅的主题或类型。
- 订阅者被添加到发布者的订阅列表中,以便在有新消息或事件时通知订阅者。
- 当发布者发布消息或触发事件时,订阅者会收到通知,并执行相应的处理逻辑。
订阅者可以随时选择取消订阅,以停止接收发布者的消息。取消订阅通常通过调用发布者的取消订阅方法,并传递订阅者对象或函数作为参数来完成。
通过发布订阅模式,订阅者可以实现松耦合的消息传递,提高系统的可扩展性和灵活性。
🦋2.1 公共事件订阅概述
动态订阅是在应用运行时,动态地调用公共事件订阅的API来实现对公共事件的订阅。这种方式适用于需要根据业务逻辑动态决定是否订阅某个公共事件的情况。例如,一个电子商务应用可能在用户下单时订阅订单创建事件,但在取消订单时取消订阅。
静态订阅是通过配置文件声明和实现继承自StaticSubscriberExtensionAbility的类来实现对公共事件的订阅。这种方式适用于需要一直订阅某个公共事件而不需要动态调整订阅的情况。例如,一个日志服务可能一直订阅用户登录事件,以记录用户的登录日志。
无论是动态订阅还是静态订阅,订阅方都可以实现自己的业务逻辑来处理接收到的公共事件。例如,订阅方可以在接收到订单创建事件时,将订单信息保存到数据库中。通过订阅公共事件,应用可以实现不同模块之间的解耦和灵活的消息传递。
🦋2.2 动态订阅公共事件
注意需要申请权限
import commonEventManager from '@ohos.commonEventManager';
import Base from '@ohos.base';
// 用于保存创建成功的订阅者对象,后续使用其完成订阅及退订的动作
let subscriber: commonEventManager.CommonEventSubscriber | null = null;
// 订阅者信息
let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
}
// 创建订阅者回调
commonEventManager.createSubscriber(subscribeInfo, (err: Base.BusinessError, data: commonEventManager.CommonEventSubscriber) => {
if (err) {
console.error(`Failed to create subscriber. Code is ${err.code}, message is ${err.message}`);
return;
}
console.info('Succeeded in creating subscriber.');
subscriber = data;
// 订阅公共事件回调
})
// 订阅公共事件回调
if (subscriber !== null) {
commonEventManager.subscribe(subscriber, (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {
if (err) {
console.error(`Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);
return;
}
})
} else {
console.error(`Need create subscriber`);
}
🦋2.3 静态订阅公共事件(仅对系统应用开放)
1、声明一个静态订阅者,首先需要在工程中新建一个ExtensionAbility, 该ExtensionAbility从StaticSubscriberExtensionAbility派生,其代码实现如下:
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
}
2、配置文件
{
"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"
}
]
}
]
......
}
}
属性名称 | 属性值 |
---|---|
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 | 订阅的目标事件列表 |
修改设备系统配置文件 /etc/static_subscriber_config.json,将静态订阅应用者的包名添加至该json文件中即可
{
"xxx",
"ohos.extension.staticSubscriber",
"xxx"
}
🦋2.3 取消动态订阅公共事件
import commonEvent from '@ohos.commonEventManager';
// 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
}
})
}
🔎3.发布
在发布订阅模型中,发布是指将消息发送到主题中。发布者通常不需要关心谁订阅了它们的消息,也不需要知道是否有订阅者。发布者只需要将消息发送到主题,然后该主题负责将消息传递给所有订阅者。
发布订阅模型可以用于实现异步通信,其中发布者和订阅者可以在互不干扰的情况下进行工作。发布者可以继续发布消息,而订阅者可以在需要时接收消息。
🦋3.1 发布不携带信息的公共事件
import commonEvent from '@ohos.commonEventManager';
// 发布公共事件
commonEvent.publish("usual.event.SCREEN_OFF", (err) => {
if (err) {
console.error(`[CommonEvent] PublishCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] Publish success`);
}
})
🦋3.2 发布携带信息的公共事件
import commonEvent from '@ohos.commonEventManager';
// 公共事件相关信息
let options = {
code: 1, // 公共事件的初始代码
data: "initial data", // 公共事件的初始数据
}
// 发布公共事件
commonEvent.publish("usual.event.SCREEN_OFF", options, (err) => {
if (err) {
console.error('[CommonEvent] PublishCallBack err=' + JSON.stringify(err));
} else {
console.info('[CommonEvent] Publish success')
}
})
🚀感谢:给读者的一封信
亲爱的读者,
我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。
如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。
我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。
如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。
再次感谢您的阅读和支持!
最诚挚的问候, “愚公搬代码”
- 点赞
- 收藏
- 关注作者
评论(0)