深入理解HarmonyOS UIAbility:生命週期、WindowStage與啟動模式探析

2023-12-04 12:02:43

本文分享自華為雲社群《深入理解HarmonyOS UIAbility:生命週期、WindowStage與啟動模式探析》,作者:檸檬味擁抱。

UIAbility元件概述

UIAbility元件是HarmonyOS中一種包含UI介面的應用元件,主要用於與使用者進行互動。每個UIAbility元件範例對應最近任務列表中的一個任務,可以包含多個頁面來實現不同功能模組。

宣告設定

為了使用UIAbility,首先需要在module.json5組態檔的abilities標籤中宣告UIAbility的相關資訊,包括名稱、入口、描述、圖示等。

{
  "module": {
    // ...
    "abilities": [
      {
        "name": "EntryAbility", // UIAbility元件的名稱
        "srcEntrance": "./ets/entryability/EntryAbility.ts", // UIAbility元件的程式碼路徑
        "description": "$string:EntryAbility_desc", // UIAbility元件的描述資訊
        "icon": "$media:icon", // UIAbility元件的圖示
        "label": "$string:EntryAbility_label", // UIAbility元件的標籤
        "startWindowIcon": "$media:icon", // UIAbility元件啟動頁面圖示資原始檔的索引
        "startWindowBackground": "$color:start_window_background", // UIAbility元件啟動頁面背景顏色資原始檔的索引
        // ...
      }
    ]
  }
}

UIAbility元件生命週期

UIAbility元件的生命週期包括四個狀態:Create、Foreground、Background、Destroy。在不同狀態之間轉換時,系統會呼叫相應的生命週期回撥函數。

Create狀態

Create狀態表示UIAbility範例建立完成時觸發,系統呼叫onCreate()回撥。在該回撥中可以進行應用初始化操作,如變數定義、資源載入等,為後續的UI介面展示做準備。

import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 應用初始化
    }
    // ...
}

WindowStageCreate和WindowStageDestroy狀態

在UIAbility範例建立完成後,在進入Foreground之前,系統會建立一個WindowStage。WindowStage建立完成後會觸發onWindowStageCreate()回撥,可以在該回撥中設定UI介面載入和訂閱WindowStage的事件。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // 設定WindowStage的事件訂閱(獲焦/失焦、可見/不可見)

        // 設定UI介面載入
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }
    // ...
}

// 對應onWindowStageCreate回撥,在UIAbility範例銷燬之前,會先進入onWindowStageDestroy回撥,可以在該回撥中釋放UI介面資源。
export default class EntryAbility extends UIAbility {
    // ...

    onWindowStageDestroy() {
        // 釋放UI介面資源
    }
}

Foreground和Background狀態

Foreground和Background狀態分別在UIAbility範例切換至前臺和切換至後臺時觸發,對應於onForeground()onBackground()回撥。在onForeground()中可以申請系統需要的資源,而在onBackground()中可以釋放UI介面不可見時無用的資源。

import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onForeground() {
        // 申請系統需要的資源,或者重新申請在onBackground中釋放的資源
    }

    onBackground() {
        // 釋放UI介面不可見時無用的資源,或者在此回撥中執行較為耗時的操作,例如狀態儲存等
    }
}

Destroy狀態

Destroy狀態在UIAbility範例銷燬時觸發,可以在onDestroy()回撥中進行系統資源的釋放、資料的儲存等操作。

import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onDestroy() {
        // 系統資源的釋放、資料的儲存等
    }
}

UIAbility元件啟動模式

UIAbility的啟動模式有三種:singleton(單範例模式)、standard(標準範例模式)、specified(指定範例模式)。

Singleton啟動模式

Singleton啟動模式為單範例模式,是預設的啟動模式。每次呼叫startAbility()方法時,如果應用程序中該型別的UIAbility範例已經存在,則複用該範例。系統中只存在唯一一個該UIAbility範例。

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "singleton",
        // ...
      }
    ]
  }
}

Standard啟動模式

Standard啟動模式為標準範例模式,每次呼叫startAbility()方法時,都會在應用程序中建立一個新的該型別UIAbility範例。在最近任務列表中可以看到多個該型別的UIAbility範例。

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "standard",
        // ...
      }
    ]
  }
}

Specified啟動模式

Specified啟動模式為指定範例模式,允許為UIAbility範例建立一個唯一的Key,後續每次呼叫startAbility()方法時,都會詢問應用使用哪個Key對應的UIAbility範例來響應請求。

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "specified",
        // ...
      }
    ]
  }
}

在指定範例模式下,需要在啟動UIAbility時傳入自定義引數,如"instanceKey",用於區分UIAbility範例。

let want = {
    deviceId: '', // deviceId為空表示本裝置
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必選
    parameters: { // 自定義資訊
        instanceKey: getInstance(),
    },
};

// context

為呼叫方UIAbility的AbilityContext
this.context.startAbility(want).then(() => {
    // ...
}).catch((err) => {
    // ...
});

在被呼叫方UIAbility的AbilityStage中,通過onAcceptWant()生命週期回撥返回一個字串Key標識,用於匹配已建立的UIAbility範例。

import AbilityStage from '@ohos.app.ability.AbilityStage';

export default class MyAbilityStage extends AbilityStage {
    onAcceptWant(want): string {
        // 在被呼叫方的AbilityStage中,針對啟動模式為specified的UIAbility返回一個UIAbility範例對應的一個Key值
        // 當前範例指的是module1 Module的FuncAbility
        if (want.abilityName === 'FuncAbility') {
            // 返回的字串Key標識為自定義拼接的字串內容
            return `ControlModule_EntryAbilityInstance_${want.parameters.instanceKey}`;
        }

        return '';
    }
}

例如,在檔案應用中,可以將檔案路徑作為一個Key標識,實現每次新建檔案都建立一個新的UIAbility範例,而開啟已儲存的檔案時重用相應的UIAbility範例。

以上就是HarmonyOS UIAbility元件的概述、宣告設定、生命週期、以及啟動模式的詳細介紹。通過了解這些知識點,開發者可以更好地利用UIAbility元件構建豐富的HarmonyOS應用。

HarmonyOS UIAbility元件進階

WindowStage和UI介面

在HarmonyOS中,UIAbility元件的介面展示主要通過WindowStage和UI介面來實現。WindowStage代表著UIAbility的視窗舞臺,而UI介面則通過載入相應的頁面來完成展示。

WindowStage的建立和銷燬

在UIAbility範例建立完成後,在進入Foreground狀態之前,系統會建立一個WindowStage。在onWindowStageCreate()回撥中,可以設定UIAbility要載入的頁面,並訂閱WindowStage的事件。

 

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // 設定WindowStage的事件訂閱(獲焦/失焦、可見/不可見)

        // 設定UI介面載入
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }

    // ...
}

對應的,在UIAbility範例銷燬之前,會先進入onWindowStageDestroy()回撥,可以在該回撥中釋放UI介面資源。

import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    // ...

    onWindowStageDestroy() {
        // 釋放UI介面資源
    }
}

UI介面的載入

onWindowStageCreate()回撥中,通過loadContent()方法設定UIAbility要載入的頁面。這裡的頁面路徑可以是相對路徑,也可以是絕對路徑。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // 設定WindowStage的事件訂閱(獲焦/失焦、可見/不可見)

        // 設定UI介面載入
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }

    // ...
}

生命週期狀態說明

UIAbility的生命週期包括Create、Foreground、Background、Destroy四個狀態,如下圖所示。

 

生命週期範例

下面以一個簡單的範例說明UIAbility的生命週期狀態變化:

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';

export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // Create狀態
        console.info('onCreate');
    }

    onWindowStageCreate(windowStage: Window.WindowStage) {
        // WindowStageCreate狀態
        console.info('onWindowStageCreate');

        // 設定UI介面載入
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }

    onForeground() {
        // Foreground狀態
        console.info('onForeground');
    }

    onBackground() {
        // Background狀態
        console.info('onBackground');
    }

    onDestroy() {
        // Destroy狀態
        console.info('onDestroy');
    }
}

在應用載入過程中,onCreate()回撥表示Create狀態,之後進入Foreground狀態前會觸發onWindowStageCreate()回撥,然後在切換至後臺和銷燬時分別觸發onBackground()onDestroy()回撥。

UIAbility元件啟動模式進階

在前面提到的UIAbility的啟動模式中,除了基本的singleton、standard、specified啟動模式外,還可以根據實際場景進行靈活的設定和使用。

使用singleton啟動模式

singleton啟動模式為單範例模式,預設情況下的啟動模式。每次呼叫startAbility()方法時,如果應用程序中已存在該型別的UIAbility範例,則系統會複用該範例。系統中只存在唯一一個該UIAbility範例。

 

在`module.json5

`組態檔中的"abilities"標籤下的"launchType"欄位設定為"singleton"即可。

{
    "module": {
        // ...
        "abilities": [
            {
                "launchType": "singleton",
                // ...
            }
        ]
    }
}

使用standard啟動模式

standard啟動模式為標準範例模式,每次呼叫startAbility()方法時,都會在應用程序中建立一個新的該型別UIAbility範例。在最近任務列表中可以看到有多個該型別的UIAbility範例。

 

module.json5組態檔中的"abilities"標籤下的"launchType"欄位設定為"standard"即可。

{
    "module": {
        // ...
        "abilities": [
            {
                "launchType": "standard",
                // ...
            }
        ]
    }
}

使用specified啟動模式

specified啟動模式為指定範例模式,允許在UIAbility範例建立之前為其建立一個唯一的字串Key。每次呼叫startAbility()方法時,會詢問應用使用哪個Key對應的UIAbility範例來響應請求。如果匹配有該UIAbility範例的Key,則直接拉起與之繫結的UIAbility範例,否則建立一個新的UIAbility範例。

 

module.json5組態檔中的"abilities"標籤下的"launchType"欄位設定為"specified"即可。

{
    "module": {
        // ...
        "abilities": [
            {
                "launchType": "specified",
                // ...
            }
        ]
    }
}

指定範例模式的使用場景

specified啟動模式適用於一些特殊場景,例如檔案應用中每次新建檔案希望都能新建一個檔案範例,而重複開啟一個已儲存的檔案時希望開啟的都是同一個檔案範例。

在使用指定範例模式時,需要在UIAbility範例建立之前為其建立一個唯一的字串Key。在啟動UIAbility時,通過自定義引數傳遞這個Key,用於匹配已建立的UIAbility範例。

例如,有兩個UIAbility:EntryAbility和FuncAbility,其中FuncAbility設定為specified啟動模式。在EntryAbility中呼叫startAbility()方法啟動FuncAbility時,需要在want引數中增加一個自定義引數來區別UIAbility範例,例如增加一個"instanceKey"自定義引數。

// 在啟動指定範例模式的UIAbility時,給每一個UIAbility範例設定一個獨立的Key標識
// 例如在檔案使用場景中,可以用檔案路徑作為Key標識
function getInstance() {
    // ...
}

let want = {
    deviceId: '', // deviceId為空表示本裝置
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必選
    parameters: { // 自定義資訊
        instanceKey: getInstance(),
    },
}

// context為呼叫方UIAbility的AbilityContext
this.context.startAbility(want).then(() => {
    // ...
}).catch((err) => {
    // ...
});

在被呼叫方UIAbility的AbilityStage中,通過onAcceptWant()生命週期回撥返回一個字串Key標識,用於匹配已建立的UIAbility範例。

import AbilityStage from '@ohos.app.ability.AbilityStage';

export default class MyAbilityStage extends AbilityStage {
    onAcceptWant(want): string {
        // 在被呼叫方的AbilityStage中,針對啟動模式為specified的UIAbility返回一個UIAbility範例對應的一個Key值
        // 當前範例指的是module1 Module的FuncAbility
        if (want.abilityName === 'FuncAbility') {
            // 返回的字串Key標識為自定義拼接的字串內容
            return `ControlModule_EntryAbilityInstance_${want.parameters.instanceKey}`;
        }

        return '';
    }
}

例如,在檔案應用中,可以對不同的檔案範例內容繫結不同的Key值。每次新建檔案時,可以傳入不同的新Key值(如將檔案的路徑作為一個Key標識),此時AbilityStage中啟動UIAbility時都會建立一個新的UIAbility範例。而當新建的檔案儲存之後,回到桌面,或者新開啟一個已儲存的檔案,再次開啟該已儲存的檔案時,AbilityStage中再次啟動該UIAbility時,開啟的仍然是之前原來已儲存的檔案介面。

// 在檔案應用中,可以對不同的檔案範例內容繫結不同的Key值
// 當每次新建檔案時,傳入不同的新Key值(如可以將檔案的路徑作為一個Key標識)
// 此時AbilityStage中啟動UIAbility時都會建立一個新的UIAbility範例
// 而當新建的檔案儲存之後,回到桌面,或者新開啟一個已儲存的檔案,再次開啟該已儲存的檔案時,
// AbilityStage中再次啟動該UIAbility時,開啟的仍然是之前原來已儲存的檔案介面

這樣,通過指定範例模式的設定,可以實現更加靈活和符合業務場景的UIAbility啟動方式。

結語

通過本文,我們詳細介紹了HarmonyOS UIAbility元件的生命週期、WindowStage的建立和銷燬、UI介面的載入,以及UIAbility的啟動模式。通過了解這些知識點,開發者可以更好地利用UIAbility元件構建豐富的HarmonyOS應用。同時,對於啟動模式的理解和靈活運用,可以根據不同業務場景選擇合適的模式,提升應用的使用者體驗。希望本文對於HarmonyOS開發者能夠提供有益的參考和幫助。

點選關注,第一時間瞭解華為雲新鮮技術~