鴻蒙HarmonyOS實戰-Stage模型(程序模型)

蜀道山QAQ發表於2024-05-25

🚀前言

程序是計算機中執行的程式的例項。它是作業系統對正在執行的程式的一種抽象概念。每個程序都有自己的獨立記憶體空間、執行狀態和執行上下文。程序可以包含一個或多個執行緒,每個執行緒可以獨立執行一部分任務。作業系統透過分配和管理程序資源來實現多工和併發執行。程序之間可以透過程序間通訊機制進行資料交換和協作。

🚀一、程序模型

🔎1.概述

在HarmonyOS中,應用的程序模型是基於多執行緒的。每個應用會執行在一個獨立的程序中,並且應用中的所有UIAbility(即應用的介面部分)會執行在同一個程序中。這意味著應用中的不同介面之間可以透過共享記憶體和訊息傳遞等方式進行通訊。

另外,HarmonyOS中的WebView擁有獨立的渲染程序。這是為了提高瀏覽器的安全性和穩定性。透過將WebView的渲染過程與應用的程序隔離開來,避免了惡意網頁對應用進行攻擊或造成應用崩潰的情況。

HarmonyOS的程序模型是基於多執行緒的,應用的介面部分執行在同一個程序中,而WebView擁有獨立的渲染程序。這樣可以提高應用的安全性和穩定性。

🚀二、公共事件簡介

🔎1.概述

HarmonyOS的公共事件服務(Common Event Service,CES)是一種機制,可以為應用程式提供訂閱、釋出和退訂公共事件的能力。這個服務使得不同應用程式之間可以進行事件的互動和通訊。

透過CES,應用程式可以定義自己的事件,並將這些事件釋出到系統的事件匯流排上。其他應用程式可以透過訂閱感興趣的事件來接收相關的通知。當有事件發生時,釋出者會將事件資訊傳送到事件匯流排,然後事件匯流排會將這些資訊傳遞給所有訂閱者。

CES提供了一種可靠的事件通訊機制,可以在不同的應用程式之間進行事件的互動。這樣,應用程式可以更方便地實現功能的整合和擴充套件。

在CES中,事件是以訊息的形式進行傳遞的,可以包含任意型別的資料。應用程式可以根據需要定義不同型別的事件,並指定事件的觸發條件和處理方式。

公共事件從系統角度可分為:系統公共事件和自定義公共事件

image

公共事件按傳送方式可分為:無序公共事件、有序公共事件和粘性公共事件

image

image

🔎2.訂閱

訂閱是指在釋出者-訂閱者模式中,訂閱者向釋出者註冊,以接收發布者傳送的訊息或事件。訂閱者可以選擇訂閱他們感興趣的特定主題或型別的訊息。

在釋出訂閱模式中,訂閱者需要執行以下步驟來進行訂閱:

  1. 建立一個訂閱者物件或函式,用於處理接收到的訊息或事件。
  2. 向釋出者註冊訂閱者。這通常透過呼叫釋出者的訂閱方法,並傳遞訂閱者物件或函式作為引數來完成。訂閱方法可能會要求提供訂閱的主題或型別。
  3. 訂閱者被新增到釋出者的訂閱列表中,以便在有新訊息或事件時通知訂閱者。
  4. 當釋出者釋出訊息或觸發事件時,訂閱者會收到通知,並執行相應的處理邏輯。

訂閱者可以隨時選擇取消訂閱,以停止接收發布者的訊息。取消訂閱通常透過呼叫釋出者的取消訂閱方法,並傳遞訂閱者物件或函式作為引數來完成。

透過釋出訂閱模式,訂閱者可以實現松耦合的訊息傳遞,提高系統的可擴充套件性和靈活性。

🦋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"
          }
        ]
      }
    ]
    ......
  }
}

image

metadata指向的二級配置檔案的通常形式如下:

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

image

修改裝置系統配置檔案 /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')
    }
})

🚀寫在最後

  • 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
  • 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
  • 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
  • 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY

image

相關文章