鴻蒙開發(fā)筆記-12-淺析UIAbility組件

  • Ability Kit(程序框架服務(wù))提供了應(yīng)用程序開發(fā)和運(yùn)行的應(yīng)用模型,是系統(tǒng)為開發(fā)者提供的應(yīng)用程序所需能力的抽象提煉,它提供了應(yīng)用程序必備的組件和運(yùn)行機(jī)制。

應(yīng)用模型

  • 隨著系統(tǒng)的演進(jìn)發(fā)展,先后提供了兩種應(yīng)用模型:
  1. FA(Feature Ability)模型:從API 7開始支持的模型,已經(jīng)不再主推。
  2. Stage模型:從API 9開始新增的模型,是目前主推且會(huì)長期演進(jìn)的模型。在該模型中,由于提供了AbilityStage、WindowStage等類作為應(yīng)用組件和Window窗口的“舞臺(tái)”,因此稱這種應(yīng)用模型為Stage模型。
  • Stage模型概念圖:
    Stage模型概念圖
  • Stage模型有三類進(jìn)程:1. 主進(jìn)程 2. ExtensionAbility進(jìn)程 3. 渲染進(jìn)程
  • AbilityStage: 每個(gè)Entry類型或者Feature類型的HAP在運(yùn)行期都有一個(gè)AbilityStage類實(shí)例。
  • UIAbility組件:是一種包含UI的應(yīng)用組件,主要用于和用戶交互。
  • ExtensionAbility組件:是一種面向特定場景的應(yīng)用組件。開發(fā)者并不直接從ExtensionAbility組件派生,而是需要使用ExtensionAbility組件的派生類。
  • WindowStage:每個(gè)UIAbility實(shí)例都會(huì)與一個(gè)WindowStage類實(shí)例綁定,該類起到了應(yīng)用進(jìn)程內(nèi)窗口管理器的作用。
  • Context:在Stage模型上,Context及其派生類向開發(fā)者提供在運(yùn)行期可以調(diào)用的各種資源和能力。

UIAbility組件概述

UIAbility是HarmonyOS應(yīng)用框架的核心組件,負(fù)責(zé)管理用戶界面與系統(tǒng)資源的交互。其核心設(shè)計(jì)理念包括:

  • 跨端遷移:支持應(yīng)用組件在不同設(shè)備間無縫遷移
  • 多端協(xié)同:實(shí)現(xiàn)多窗口、多任務(wù)并行處理
  • 窗口管理:每個(gè)UIAbility實(shí)例對應(yīng)一個(gè)獨(dú)立任務(wù)窗口, 支持單實(shí)例/多實(shí)例運(yùn)行模式
  • 生命周期感知:提供完整的生命周期回調(diào)體系
  • 多模塊交互:支持與Service/ExtensionAbility深度協(xié)作
  • 狀態(tài)可移植:通過統(tǒng)一的上下文管理機(jī)制(UIAbilityContext)實(shí)現(xiàn)運(yùn)行狀態(tài)的持久化存儲(chǔ)與恢復(fù)
  • 原子化調(diào)度:系統(tǒng)調(diào)度的最小單位,支持獨(dú)立部署與運(yùn)行
  • UI容器屬性:通過WindowStage管理ArkUI頁面棧

聲明配置示例(module.json5):

{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility", // UIAbility組件的名稱
        "launchType": "singleton", //啟動(dòng)模式
        "srcEntry": "./ets/entryability/EntryAbility.ets", // UIAbility組件的代碼路徑
        "description": "$string:EntryAbility_desc",// UIAbility組件的描述信息
        "icon": "$media:layered_image",// UIAbility組件的圖標(biāo)
        "label": "$string:EntryAbility_label", // UIAbility組件的標(biāo)簽
        "startWindowIcon": "$media:startIcon", // UIAbility組件啟動(dòng)頁面圖標(biāo)資源文件的索引
        "startWindowBackground": "$color:start_window_background",// UIAbility組件啟動(dòng)頁面背景顏色資源文件的索引
        "exported": true,
      }
    ]
  }
}

生命周期管理

生命周期狀態(tài)機(jī)包含6種狀態(tài):Create → WindowStageCreate → Foreground → Background → WindowStageDestroy → Destroy

創(chuàng)建階段

export default class MainAbility extends UIAbility {
  onCreate(want: Want, launchParam: LaunchParam) {
    console.log("Ability創(chuàng)建");
    // 初始化全局資源
    this.globalData = { count: 0 };
  }
}

窗口階段

onWindowStageCreate(windowStage: WindowStage) {
  console.log("窗口創(chuàng)建完成");
  // 加載主頁面
  windowStage.loadContent('pages/Index', (err) => {
    if (err) console.error('加載失敗:', err);
  });
  
  // 監(jiān)聽窗口事件
  windowStage.on('windowStageEvent', (event) => {
    switch(event) {
      case WindowStageEventType.SHOWN:
        this.handleWindowFocus();  
        break;
      case 'ACTIVE':
        console.log('窗口獲取焦點(diǎn)');
        break;
      case 'INACTIVE':
        console.log('窗口失去焦點(diǎn)');
        break;
    }
  });
}

onWindowStageWillDestroy(windowStage: window.WindowStage) {
    // 釋放通過windowStage對象獲取的資源
}

onWindowStageDestroy(): void {
    // 釋放UI資源
    // 例如在onWindowStageDestroy()中注銷獲焦/失焦等WindowStage事件
}

前后臺(tái)切換

onForeground() {
  console.log("進(jìn)入前臺(tái)");
  // 申請定位權(quán)限等前臺(tái)資源
  requestLocationPermission();
}

onBackground() {
  // 釋放內(nèi)存資源
  this.globalData = null;
}

銷毀階段

onDestroy() {
  console.log("Ability銷毀");
  // 清理殘留資源
  if (this.timer) {
    clearInterval(this.timer);
  }
}

啟動(dòng)模式

模式 特性 使用場景
singleton 默認(rèn),單實(shí)例, 主界面/全局服務(wù)
multiton 多實(shí)例,獨(dú)立運(yùn)行 并行任務(wù)處理
specified 指定Key標(biāo)識(shí)實(shí)例 文檔編輯器等場景

1. singleton啟動(dòng)模式:

  • 單實(shí)例模式(默認(rèn)),共享同一上下文。
  • 每次調(diào)用startAbility()方法時(shí),如果應(yīng)用進(jìn)程中該類型的UIAbility實(shí)例已經(jīng)存在,則復(fù)用系統(tǒng)中的UIAbility實(shí)例。
  • 系統(tǒng)中只存在唯一一個(gè)該UIAbility實(shí)例,即在最近任務(wù)列表中只存在一個(gè)該類型的UIAbility實(shí)例。(進(jìn)入該UIAbility的onNewWant()回調(diào))
  • 當(dāng)應(yīng)用的UIAbility實(shí)例已創(chuàng)建,且UIAbility配置為singleton啟動(dòng)模式時(shí),再次調(diào)用startAbility()方法啟動(dòng)該UIAbility實(shí)例時(shí),只會(huì)進(jìn)入該UIAbility的onNewWant()回調(diào),不會(huì)進(jìn)入其onCreate()和onWindowStageCreate()生命周期回調(diào)。應(yīng)用可以在該回調(diào)中更新要加載的資源和數(shù)據(jù)等,用于后續(xù)的UI展示。

2. multiton啟動(dòng)模式:

  • 多實(shí)例模式。
  • 每次調(diào)用startAbility()方法時(shí),都會(huì)在應(yīng)用進(jìn)程中創(chuàng)建一個(gè)新的該類型UIAbility實(shí)例。即在最近任務(wù)列表中可以看到有多個(gè)該類型的UIAbility實(shí)例。

3. specified啟動(dòng)模式:

  • 指定實(shí)例模式,針對一些特殊場景使用(例如文檔應(yīng)用中每次新建文檔希望都能新建一個(gè)文檔實(shí)例,重復(fù)打開一個(gè)已保存的文檔希望打開的都是同一個(gè)文檔實(shí)例)。
  • 在創(chuàng)建UIAbility實(shí)例之前,開發(fā)者可以為該實(shí)例指定一個(gè)唯一的字符串Key,這樣在調(diào)用startAbility()方法時(shí),應(yīng)用就可以根據(jù)指定的Key來識(shí)別響應(yīng)請求的UIAbility實(shí)例。在EntryAbility中,調(diào)用startAbility()方法時(shí),可以在want參數(shù)中增加一個(gè)自定義參數(shù),例如instanceKey,以此來區(qū)分不同的UIAbility實(shí)例。
// AbilityStage實(shí)現(xiàn)
export default class MyAbilityStage extends AbilityStage {
  onAcceptWant(want: Want): string {
    return `SPEC_KEY_${want.parameters.docId}`;
  }
}

// 啟動(dòng)時(shí)指定Key
let want = {
  abilityName: 'SpecifiedAbility',
  parameters: { docId: 'DOC_2023' }
};

數(shù)據(jù)同步機(jī)制

EventHub事件總線

// 發(fā)布事件
this.context.eventHub.emit('userUpdated', { id: 1, name: 'Alice' });

// 訂閱事件
this.context.eventHub.on('userUpdated', (user) => {
  console.log('用戶信息更新:', user);
});

應(yīng)用級存儲(chǔ)

// 全局存儲(chǔ)(跨Ability)
AppStorage.set('userInfo', { token: 'abc123' });

// 局部存儲(chǔ)(當(dāng)前Ability)
LocalStorage.set('settings', { theme: 'dark' });

跨Ability交互

參數(shù)傳遞

// 啟動(dòng)時(shí)傳遞參數(shù)
let want = {
  abilityName: 'DetailAbility',
  parameters: { id: 123, type: 'video' }
};

// 接收參數(shù)
export default class DetailAbility extends UIAbility {
  onCreate(want: Want) {
    let params = want.parameters;
    console.log('接收參數(shù):', params.id, params.type);
  }
}

結(jié)果回調(diào)

// 發(fā)起請求
startAbilityForResult(want).then((result) => {
  console.log('返回?cái)?shù)據(jù):', result.data);
});

// 返回結(jié)果
terminateSelfWithResult({
  resultCode: 200,
  want: {
    parameters: { success: true }
  }
});

實(shí)戰(zhàn)技巧

啟動(dòng)UIAbility的指定頁面

  • 一個(gè)UIAbility可以對應(yīng)多個(gè)頁面,在不同的場景下啟動(dòng)該UIAbility時(shí)需要展示不同的頁面。
  • UIAbility的啟動(dòng)分為兩種情況:UIAbility冷啟動(dòng)和UIAbility熱啟動(dòng)。
    1. UIAbility冷啟動(dòng):指的是UIAbility實(shí)例處于完全關(guān)閉狀態(tài)下被啟動(dòng),這需要完整地加載和初始化UIAbility實(shí)例的代碼、資源等。
    2. UIAbility熱啟動(dòng):指的是UIAbility實(shí)例已經(jīng)啟動(dòng)并在前臺(tái)運(yùn)行過,由于某些原因切換到后臺(tái),再次啟動(dòng)該UIAbility實(shí)例,這種情況下可以快速恢復(fù)UIAbility實(shí)例的狀態(tài)。
  • 調(diào)用方UIAbility指定啟動(dòng)頁面:通過want中的parameters參數(shù)增加一個(gè)自定義參數(shù)傳遞頁面跳轉(zhuǎn)信息。
// 冷啟動(dòng)指定頁面
if (this.isColdStart) {
  windowStage.loadContent('pages/Login');
} else {
  router.pushUrl({ url: 'pages/Dashboard' });
}

// 熱啟動(dòng)頁面跳轉(zhuǎn)
this.router.replaceUrl({ url: 'pages/Profile' });

錯(cuò)誤處理

try {
  await this.context.startAbility(want);
} catch (err) {
  if (err.code === 1008500011) {
    showToast('文件傳輸權(quán)限不足');
  } else {
    console.error('啟動(dòng)失敗:', err);
  }
}
  • 通過掌握UIAbility的生命周期管理、啟動(dòng)模式配置、數(shù)據(jù)同步機(jī)制及跨組件交互技巧,開發(fā)者可以構(gòu)建高效、靈活的HarmonyOS應(yīng)用架構(gòu),實(shí)現(xiàn)真正的分布式能力。

我是今陽,如果想要進(jìn)階和了解更多的干貨,歡迎關(guān)注wxgzh “今陽說” 接收我的最新文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容