Wsh's blog Wsh's blog
首页
  • 基础知识
  • ArkUI
  • UIAbility
  • 组件通信方式
  • 前端缓存
  • React
  • typescript
  • javascript
  • flutter
  • node
  • webpack
web3D😉
宝库📰
  • 分类
  • 标签
  • 归档
龙哥的大🐂之路 (opens new window)
GitHub (opens new window)

wsh

热爱前端的程序媛
首页
  • 基础知识
  • ArkUI
  • UIAbility
  • 组件通信方式
  • 前端缓存
  • React
  • typescript
  • javascript
  • flutter
  • node
  • webpack
web3D😉
宝库📰
  • 分类
  • 标签
  • 归档
龙哥的大🐂之路 (opens new window)
GitHub (opens new window)
  • 基础知识
  • ATKTS
  • UIAbility
    • UIAbility组件概念
      • 声明配置
    • UIAbility组件声明周期
      • Create 状态
    • UIAbility组件启动模式
      • singleton(单实例模式)
      • multition(多实例模式)
      • specified(指定实例模式)
    • UIAbility 组件基本用法
      • 指定UIAbility的启动页面
      • 获取UIAbility的上下文信息
    • UIAbility组件与UI的数据同步
      • 使用EventHub进行数据通信
      • 使用globalThis进行数据同步
      • 使用AppStorage/LocalStorage进行数据同步
    • UiAbility组件内交互(设备内)
      • 启动应用内的UIAbility
      • 启动应用内的UIAbility并获取返回结果
      • 启动其他应用的UIAbility
      • 启动其他应用的UIAbility并获取返回结果
      • 启动UIAbility的指定页面
  • 组件通信方式
  • harmonyOS
2025-01-07
目录

UIAbility

# UIAbility组件概念

UIAbility组件是一种包括UI界面的应用组件,主要用于和用户交互。 UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口,一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近的任务列表中的任务。

# 声明配置

为使应用能够正常使用UIAbility, 需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息。

{
  "module": {
    //...
    "abilities": [
      {
        "name": "EntryAbility", // UIAbility 组件的名称
        "srcEntry": "./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组件实例会在其生命周期的不同状态进行转换。

UIAbility组件包括四个生命周期: Create、 Foreground、 Background、 Destroy

# Create 状态

该状态是在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行页面初始化操作,例如变量定义资源加载等,用于后续的UI界面展示

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

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

# windowStageCreate 和 windowStageDestroy 状态

UIAbility实例在进入到 Create之后,进入Foreground之前,系统会创建一个windowStage。

WindowStage创建完成以后,会进入到onWindowStageCreate() 回调,可以在这个时期设置UI界面加载、设置WindowStage的事件订阅。

在onWindowStageCreate() 回调里加载loadContent方法指定加载的页面,并根据需要订阅WindowStage事件(获焦/失焦、可见/不可见)

# Foreground和Background状态

Foreground 和Background在UIAbility实例切换到前台和后台时触发。对应于onForeground 和onBackground回调

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示例:

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

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }

  onWindowStageDestroy() {
    // Main window is destroyed, release UI related resources
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground() {
    // Ability has brought to foreground
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground() {
    // Ability has back to background
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  }
}

# UIAbility组件启动模式

三种模块:

  • singleton(单实例模式)
  • multition(多实例模式)
  • specified(指定实例模式)
{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "singleton",
        // ...
      }
    ]
  }
}

# singleton(单实例模式)

每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。

系统中只存在一个UIAbility实例

# multition(多实例模式)

multition 启动模式 为多实例模式,每次调用startAbility() 方法时,都会在进程中创建一个新的该类型UIAbility实例。

# specified(指定实例模式)

specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的是同一个文档实例)

每个实例绑定一个唯一的key(instanceKey),如果匹配有该UIAbility实例的Key,则直接拉起与之绑定的UIAbility 实例。否则创建一个新的UIAbility实例。

// 在启动指定实例模式的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 组件基本用法

指定UIAbility 启动页面和获取UIAbility上下文UIAbilityContext

# 指定UIAbility的启动页面

应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有加载默认页面而白屏

在UIAbility的 onWindowStageCreate() 调用loadContent() 设置启动页面

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

export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // Main window is created, set main page for this ability
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }

    // ...
}

# 获取UIAbility的上下文信息

通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如startAbility()、connectServiceExtensionAbility()、terminateSelf()等)

  • 在UIAbility中可以通过this.context获取UIAbility实例的上下文信息。
import UIAbility from '@ohos.app.ability.UIAbility';

export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 获取UIAbility实例的上下文
        let context = this.context;

        // ...
    }
}

  • 在页面中获取UIAbility实例的上下文信息,包括导入依赖资源context模块和在组件中定义一个context变量两个部分。
import common from '@ohos.app.ability.common';

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;

  startAbilityTest() {
    let want = {
      // Want参数信息
    };
    this.context.startAbility(want);
  }

  // 页面展示
  build() {
    // ...
  }
}


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

@Entry
@Component
struct Index {

  startAbilityTest() {
    let context = getContext(this) as common.UIAbilityContext;
    let want = {
      // Want参数信息
    };
    context.startAbility(want);
  }

  // 页面展示
  build() {
    // ...
  }
}

# UIAbility组件与UI的数据同步

  • 使用EventHub进行数据通信:基于发布订阅模式来实现,事件需要先订阅后发布,订阅者收到消息后进行处理。

  • 使用globalThis进行数据同步:ArkTS引擎实例内部的一个全局对象,在ArkTS引擎实例内部都能访问。

  • 使用AppStorage/LocalStorage进行数据同步:ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。

# 使用EventHub进行数据通信

执行订阅操作


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

const TAG: string = '[Example].[Entry].[EntryAbility]';

export default class EntryAbility extends UIAbility {
    func1(...data) {
        // 触发事件,完成相应的业务操作
        console.info(TAG, '1. ' + JSON.stringify(data));
    }

    onCreate(want, launch) {
        // 获取eventHub
        let eventhub = this.context.eventHub;
        // 执行订阅操作
        eventhub.on('event1', this.func1);
        eventhub.on('event1', (...data) => {
            // 触发事件,完成相应的业务操作
            console.info(TAG, '2. ' + JSON.stringify(data));
        });
    }
}

触发该事件

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

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;

  eventHubFunc() {
    // 不带参数触发自定义“event1”事件
    this.context.eventHub.emit('event1');
    // 带1个参数触发自定义“event1”事件
    this.context.eventHub.emit('event1', 1);
    // 带2个参数触发自定义“event1”事件
    this.context.eventHub.emit('event1', 2, 'test');
    // 开发者可以根据实际的业务场景设计事件传递的参数
  }

  // 页面展示
  build() {
    // ...
  }
}

# 使用globalThis进行数据同步

使用globalThis进行数据同步

使用:

//数据存入globalThis中
 globalThis.xxx= [数据];
//需要使用的地方调用
let a = globalThis.xxx

UIAbility和UIAbility之间使用globalThis 使用的注意事项

  • 存放名称不要相同,Stage模型下进程内的UIAbility组件共享ArkTS引擎实例,使用globalThis时需要避免存放相同名称的对象。例如AbilityA和AbilityB可以使用globalThis共享数据,在存放相同名称的对象时,先存放的对象会被后存放的对象覆盖。
  • 用完将其赋值为null,以减少对应用内存的占用。对于绑定在globalThis上的对象,其生命周期与ArkTS虚拟机实例相同,建议在使用完成之后将其赋值为null,以减少对应用内存的占用。

# 使用AppStorage/LocalStorage进行数据同步

  • AppStorage:是全局状态管理器,适应于 多个 UIAbility 共享同一份数据的情况
  • LocalStorage:是局部状态管理器,适应于单个UIAbility 内部使用的状态数据

# UiAbility组件内交互(设备内)

UIAbility 是系统调度的最小单元,在设备内的功能模块跳转时,会涉及到启动的特定的UIAbility,该UIAbility 应该是应用内的其他UIAbility,也可以是其他应用的UIAbility(比如第三方支付)

# 启动应用内的UIAbility

let wantInfo = {
    deviceId: '', // deviceId为空表示本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自定义信息
        info: '来自EntryAbility Index页面',
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
    // ...
}).catch((err) => {
    // ...
})

接受参数

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

export default class FuncAbility extends UIAbility {
    onCreate(want, launchParam) {
    // 接收调用方UIAbility传过来的参数
        let funcAbilityWant = want;
        let info = funcAbilityWant?.parameters?.info;
        // ...
    }
}

停止当前UIAbility实例

// context为需要停止的UIAbility实例的AbilityContext
this.context.terminateSelf((err) => {
    // ...
});

# 启动应用内的UIAbility并获取返回结果

let wantInfo = {
    deviceId: '', // deviceId为空表示本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自定义信息
        info: '来自EntryAbility Index页面',
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {
    // ...
}).catch((err) => {
    // ...
})
const RESULT_CODE: number = 1001;
let abilityResult = {
    resultCode: RESULT_CODE,
    want: {
        bundleName: 'com.example.myapplication',
        abilityName: 'FuncAbility',
        moduleName: 'module1',
        parameters: {
            info: '来自FuncAbility Index页面',
        },
    },
}
// context为被调用方UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {
    // ...
});
const RESULT_CODE: number = 1001;

// ...

// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {
    if (data?.resultCode === RESULT_CODE) {
        // 解析被调用方UIAbility返回的信息
        let info = data.want?.parameters?.info;
        // ...
    }
}).catch((err) => {
    // ...
})

# 启动其他应用的UIAbility

启动UIAbility 有显式启动和隐式启动 两种

  • 显式Want启动:启动一个确定应用的UIAbility,在want参数中需要设置该应用bundleName和abilityName,当需要拉起某个明确的UIAbility时,通常使用显式Want启动方式。

  • 隐式启动:根据匹配条件由用户选择启动哪个UIAbility,不明确指出要启动哪一个UIAbility(abilityName参数未设置)

# 启动其他应用的UIAbility并获取返回结果

# 启动UIAbility的指定页面

# 调用方UIAbility指定启动页面

let wantInfo = {
    deviceId: '', // deviceId为空表示本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自定义参数传递页面信息
        router: 'funcA',
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
    // ...
}).catch((err) => {
    // ...
})

# 目标UIAbility首次启动

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

export default class FuncAbility extends UIAbility {
    funcAbilityWant;

    onCreate(want, launchParam) {
        // 接收调用方UIAbility传过来的参数
        this.funcAbilityWant = want;
    }

    onWindowStageCreate(windowStage: Window.WindowStage) {
        // Main window is created, set main page for this ability
        let url = 'pages/Index';
        if (this.funcAbilityWant?.parameters?.router) {
            if (this.funcAbilityWant.parameters.router === 'funcA') {
                url = 'pages/Second';
            }
        }
        windowStage.loadContent(url, (err, data) => {
            // ...
        });
    }
}

# 目标UIAbility非首次启动

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

export default class FuncAbility extends UIAbility {
    onNewWant(want, launchParam) {
        // 接收调用方UIAbility传过来的参数
        globalThis.funcAbilityWant = want;
        // ...
    }
}
import router from '@ohos.router';

@Entry
@Component
struct Index {
  onPageShow() {
    let funcAbilityWant = globalThis.funcAbilityWant;
    let url2 = funcAbilityWant?.parameters?.router;
    if (url2 && url2 === 'funcA') {
      router.replaceUrl({
        url: 'pages/Second',
      })
    }
  }

  // 页面展示
  build() {
    // ...
  }
}

提示

当被调用方Ability的启动模式设置为multiton启动模式时,每次启动都会创建一个新的实例,那么onNewWant()回调就不会被用到。

ATKTS
组件通信方式

← ATKTS 组件通信方式→

最近更新
01
组件通信方式
01-07
02
ATKTS
01-06
03
基础知识
01-06
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Wsh | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式