未验证 提交 b7182db1 编写于 作者: O openharmony_ci 提交者: Gitee

!18092 优化代码格式、优化部分描述,应用模型基本概念中优化对应的概念图示,同步部分Master分支内容

Merge pull request !18092 from zyjhandsome/OpenHarmony-3.2-Release
......@@ -55,7 +55,7 @@
- [Want概述](want-overview.md)
- [显式Want与隐式Want匹配规则](explicit-implicit-want-mappings.md)
- [常见action与entities](actions-entities.md)
- [使用显式Want启动Ability](ability-startup-with-explicit-want.md)
- [使用显式Want启动应用组件](ability-startup-with-explicit-want.md)
- [使用隐式Want打开网址](ability-startup-with-implicit-want.md)
- [应用间使用Want分享数据](data-share-via-want.md)
- [组件启动规则(Stage模型)](component-startup-rules.md)
......@@ -63,6 +63,7 @@
- [流转概述](inter-device-interaction-hop-overview.md)
- [跨端迁移(仅对系统应用开放)](hop-cross-device-migration.md)
- [多端协同(仅对系统应用开放)](hop-multi-device-collaboration.md)
- [订阅系统环境变量的变化](subscribe-system-environment-variable-changes.md)
- 进程间通信
- [进程模型](process-model-stage.md)
- 公共事件
......@@ -78,10 +79,12 @@
- [线程模型](thread-model-stage.md)
- [使用Emitter进行线程间通信](itc-with-emitter.md)
- [使用Worker进行线程间通信](itc-with-worker.md)
- 任务(Mission)管理
- [任务(Mission)管理场景介绍](mission-management-overview.md)
- [任务(Mission)与启动模式](mission-management-launch-type.md)
- 任务管理
- [任务管理场景介绍](mission-management-overview.md)
- [任务管理与启动模式](mission-management-launch-type.md)
- [页面栈及任务链](page-mission-stack.md)
- [设置任务快照的图标和名称](mission-set-icon-name-for-task-snapshot.md)
- [Stage模型应用配置文件](config-file-stage.md)
- FA模型开发指导
- [FA模型开发概述](fa-model-development-overview.md)
- FA模型应用组件
......
# 使用显式Want启动Ability
# 使用显式Want启动应用组件
在应用使用场景中,当用户在应用内点击某个按钮时,经常需要拉起指定UIAbility组件来完成某些特定任务。在启动UIAbility时,指定了abilityName和bundleName参数,可以使用显式Want方式启动UIAbility。显式Want的使用
......
......@@ -5,21 +5,21 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// ...
...
"skills": [
{
"entities": [
"entity.system.home",
"entity.system.browsable"
// ...
...
],
"actions": [
"action.system.home",
"ohos.want.action.viewData"
// ...
...
],
"uris": [
{
......@@ -31,9 +31,9 @@
},
{
"scheme": "http",
// ...
...
}
// ...
...
]
}
]
......@@ -59,19 +59,18 @@ function implicitStartAbility() {
'uri': 'https://www.test.com:8080/query/student'
}
context.startAbility(wantInfo).then(() => {
// ...
...
}).catch((err) => {
// ...
...
})
}
```
匹配过程分析:
1. 调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions不为空且包含调用方传入的want参数的action,action匹配成功。
2. 调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities不为空且包含调用方传入的want参数的entities,entities匹配成功。
3. 待匹配Ability的skills配置中内uris拼接为`https://www.test.com:8080/query*` (其中*表示通配符),包含调用方传入的want参数的uri,uri匹配成功。
4. 调用方传入的want参数的type不为空,待匹配Ability的skills配置中的type不为空且包含调用方传入的want参数的type,type匹配成功。
1. 调用方传入的want参数的action不为空,待匹配目标应用组件的skills配置中的actions不为空且包含调用方传入的want参数的action,action匹配成功。
2. 调用方传入的want参数的entities不为空,待匹配目标应用组件的skills配置中的entities不为空且包含调用方传入的want参数的entities,entities匹配成功。
3. 待匹配目标应用组件的skills配置中内uris拼接为`https://www.test.com:8080/query*`(其中*表示通配符),包含调用方传入的want参数的uri,uri匹配成功。
当存在多个匹配的应用时,系统将弹出应用选择框供用户选择。示意效果如下图所示。
![stage-want1](figures/stage-want1.png)
![](figures/ability-startup-with-implicit-want1.png)
......@@ -30,14 +30,14 @@ DevEco Studio默认工程中未自动生成AbilityStage,如需要使用Ability
}
```
4.[module.json5配置文件](../quick-start/module-configuration-file.md)`srcEntry`参数中配置Module所对应的代码路径
4.[module.json5配置文件](../quick-start/module-configuration-file.md),通过配置 `srcEntry` 参数来指定模块对应的代码路径,以作为HAP加载的入口
```json
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",
// ...
...
}
}
```
......@@ -45,7 +45,7 @@ DevEco Studio默认工程中未自动生成AbilityStage,如需要使用Ability
[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md)拥有[`onCreate()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate)生命周期回调和[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)[`onConfigurationUpdated()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate)[`onMemoryLevel()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonmemorylevel)事件回调。
- [`onCreate()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate)生命周期回调:在开始加载对应Module的第一个UIAbility实例之前会先创建AbilityStage,并在AbilityStage创建完成之后执行其onCreate()生命周期回调。AbilityStage模块提供在Module加载的时候,通知开发者,可以在此进行该Module的初始化(如资源预加载,线程创建等)能力。
- [`onCreate()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate)生命周期回调:在开始加载对应Module的第一个UIAbility实例之前会先创建AbilityStage,并在AbilityStage创建完成之后执行其`onCreate()`生命周期回调。AbilityStage模块提供在Module加载的时候,通知开发者,可以在此进行该Module的初始化(如资源预加载,线程创建等)能力。
- [`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)事件回调:UIAbility[指定实例模式(specified)](uiability-launch-type.md#specified启动模式)启动时候触发的事件回调,具体使用请参见[UIAbility启动模式综述](uiability-launch-type.md)
......
......@@ -16,7 +16,7 @@ AccessibilityExtensionAbility基于ExtensionAbility框架,提供无障碍扩
- [如何处理一个无障碍事件](#如何处理一个无障碍事件)
- [如何声明无障碍扩展服务具备的能力](#如何声明无障碍扩展服务具备的能力)
- [如何开启自定义的无障碍扩展服务](#如何开启自定义的无障碍扩展服务)
- [相关实例](#相关实)
- [相关示例](#相关示)
## 如何创建一个无障碍扩展服务
......@@ -38,15 +38,15 @@ import AccessibilityExtensionAbility from '@ohos.application.AccessibilityExtens
class AccessibilityExtAbility extends AccessibilityExtensionAbility {
onConnect() {
console.log('AccessibilityExtAbility onConnect');
console.info('AccessibilityExtAbility onConnect');
}
onDisconnect() {
console.log('AccessibilityExtAbility onDisconnect');
console.info('AccessibilityExtAbility onDisconnect');
}
onAccessibilityEvent(accessibilityEvent) {
console.log('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
console.info('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
}
}
......@@ -67,9 +67,9 @@ export default AccessibilityExtAbility;
```typescript
onAccessibilityEvent(accessibilityEvent) {
console.log('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
console.info('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
if (accessibilityEvent.eventType === 'pageStateUpdate') {
console.log('AccessibilityExtAbility onAccessibilityEvent: pageStateUpdate');
console.info('AccessibilityExtAbility onAccessibilityEvent: pageStateUpdate');
// TODO: 自定义相关逻辑开发
}
}
......@@ -80,13 +80,13 @@ onAccessibilityEvent(accessibilityEvent) {
## 如何声明无障碍扩展服务具备的能力
在完成自定义无障碍扩展服务的逻辑开发后,还需要在工程中Module对应的module.json5文件中加入新增扩展服务的配置信息,其中`srcEnty`标签为`extensionAbility`对应的路径。需要注意的一点是配置信息中的type标签要按照与无障碍子系统的约定进行配置,固定为`accessibility`,否则将无法正常连接。
在完成自定义无障碍扩展服务的逻辑开发后,还需要在工程中Module对应的module.json5文件中加入新增扩展服务的配置信息,其中`srcEntry`标签为`extensionAbility`对应的路径。需要注意的一点是配置信息中的type标签要按照与无障碍子系统的约定进行配置,固定为`accessibility`,否则将无法正常连接。
```json
"extensionAbilities": [
{
"name": "AccessibilityExtAbility",
"srcEnty": "./ets/AccessibilityExtAbility/AccessibilityExtAbility.ts",
"srcEntry": "./ets/AccessibilityExtAbility/AccessibilityExtAbility.ts",
"label": "$string:MainAbility_label",
"description": "$string:MainAbility_desc",
"type": "accessibility",
......@@ -118,9 +118,9 @@ onAccessibilityEvent(accessibilityEvent) {
若开启或关闭成功,则会打印`enable ability successfully``disable ability successfully`
## 相关
## 相关
针对AccessibilityExtensionAbility开发,有以下相关例可供参考:
针对AccessibilityExtensionAbility开发,有以下相关例可供参考:
- [AccessibilityExtAbility的创建和使用(ArkTS)(API 9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/ability/AccessibilityExtAbility)
[AccessibilityExtAbility的创建和使用(ArkTS)(API 9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/AccessibilityExtAbility)
# 常见action与entities
**[action](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction)**:表示调用方要执行的通用操作(如查看、分享、应用详情)。在隐式Want中,您可定义该字段,配合uri或parameters来表示对数据要执行的操作。如打开,查看该uri数据。例如,当uri为一段网址,action为ohos.want.action.viewData则表示匹配可查看该网址的Ability。在Want内声明action字段表示希望被调用方应用支持声明的操作。在被调用方应用配置文件skills字段内声明actions表示该应用支持声明操作。
**action**:表示调用方要执行的通用操作(如查看、分享、应用详情)。在隐式[Want](../reference/apis/js-apis-app-ability-want.md)中,您可定义该字段,配合uri或parameters来表示对数据要执行的操作。如打开,查看该uri数据。例如,当uri为一段网址,action为`ohos.want.action.viewData`则表示匹配可查看该网址的应用组件。在[Want](../reference/apis/js-apis-app-ability-want.md)内声明action字段表示希望被调用方应用支持声明的操作。在被调用方应用配置文件skills字段内声明actions表示该应用支持声明操作。
**常见action**
......@@ -15,11 +13,9 @@
- ACTION_VIEW_MULTIPLE_DATA:发送多个数据记录的操作。
**entities**:表示目标应用组件的类别信息(如浏览器、视频播放器),在隐式Want中是对action的补充。在隐式Want中,开发者可定义该字段,来过滤匹配应用的类别,例如必须是浏览器。在Want内声明entities字段表示希望被调用方应用属于声明的类别。在被调用方应用配置文件skills字段内声明entites表示该应用支持的类别。
**[entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity)**:表示目标Ability的类别信息(如浏览器、视频播放器),在隐式Want中是对action的补充。在隐式Want中,开发者可定义该字段,来过滤匹配应用的类别,例如必须是浏览器。在Want内声明entities字段表示希望被调用方应用属于声明的类别。在被调用方应用配置文件skills字段内声明entites表示该应用支持的类别。
**常用entities**
**常见entities**
- ENTITY_DEFAULT:默认类别无实际意义。
......
......@@ -13,8 +13,8 @@ startAbility接口由FA模型切换到Stage模型的示例:
import fa from '@ohos.ability.featureAbility';
let parameter = {
"want": {
bundleName: "ohos.samples.demo",
abilityName: "ohos.samples.demo.MainAbility"
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.EntryAbility"
}
}
fa.startAbility(parameter).then((data) => {
......@@ -30,8 +30,8 @@ startAbility接口由FA模型切换到Stage模型的示例:
// context为Ability对象的成员,在非Ability对象内部调用需要
// 将Context对象传递过去
let wantInfo = {
bundleName: "ohos.samples.demo",
abilityName: "ohos.samples.demo.MainAbility"
bundleName: "com.example.myapplication",
abilityName: "EntryAbility"
};
this.context.startAbility(wantInfo).then((data) => {
console.info('startAbility success.');
......
......@@ -21,11 +21,11 @@ app.json5中对原先config.json中的[deviceConfig](../quick-start/deviceconfig
**表2** 配置文件deviceConfig标签差异对比
| FA中deviceConfig标签 | 描述 | stage模型中 | 差异比对 |
| FA中deviceConfig标签 | 描述 | stage模型中 | 差异比对 |
| -------- | -------- | -------- | -------- |
| deviceConfig标签 | deviceConfig标签配置了设备信息 | / | Stage模型中没有该标签,直接在app标签下配置设备信息 |
| process | 标识应用或者Ability的进程名。如果在deviceConfig标签下配置了process标签,则该应用的所有Ability都运行在这个进程中。如果在abilities标签下也为某个Ability配置了process标签,则该Ability就运行在这个进程中。 | / | Stage模型不支持配置进程名称 |
| keepAlive | 标识应用是否始终保持运行状态,仅支持系统应用配置,三方应用配置不生效。 | / | Stage模型不支持系统应用模型管控方式变更 |
| supportBackup | 标识应用是否支持备份和恢复。 | / | Stage模型不支持 |
| compressNativeLibs | 标识libs库是否以压缩存储的方式打包到HAP包。 | / | Stage模型不支持 |
| network | 标识网络安全性配置。 | / | Stage模型不支持 |
| deviceConfig标签 | deviceConfig标签配置了设备信息 | / | Stage模型中没有该标签,直接在app标签下配置设备信息 |
| process | 标识应用或者UIAbility的进程名。如果在deviceConfig标签下配置了process标签,则该应用的所有UIAbility都运行在这个进程中。如果在abilities标签下也为某个UIAbility配置了process标签,则该UIAbility就运行在这个进程中。 | / | Stage模型不支持配置进程名称 |
| keepAlive | 标识应用是否始终保持运行状态,仅支持系统应用配置,三方应用配置不生效。 | / | Stage模型不支持系统应用模型管控方式变更 |
| supportBackup | 标识应用是否支持备份和恢复。 | / | Stage模型不支持 |
| compressNativeLibs | 标识libs库是否以压缩存储的方式打包到HAP。 | / | Stage模型不支持 |
| network | 标识网络安全性配置。 | / | Stage模型不支持 |
# 应用/组件级配置
开发者在开发应用时,需要配置应用的一些标签,例如应用的包名、图标等标识特征的属性。这一章节描述了开发者在开发应用时需要配置的一些关键标签。
开发者在开发应用时,需要配置应用的一些标签,例如应用的Bundle名称、图标等标识特征的属性。这一章节描述了开发者在开发应用时需要配置的一些关键标签。
- **应用包名配置**
......@@ -22,7 +22,7 @@
"actions": ["action.system.home"]
}
]
// ...
...
}
```
......@@ -36,4 +36,4 @@
- **组件权限申请配置**
组件权限申请配置需在confog.json中的module标签下配置reqPermission字段。来声明需要申请权限的名称,申请权限的原因以及权限使用的场景。组件权限申请可以参考[reqPermission标签说明](../quick-start/module-structure.md)
\ No newline at end of file
组件权限申请配置需在confog.json中的module标签下配置reqPermission字段。来声明需要申请权限的名称,申请权限的原因以及权限使用的场景。组件权限申请可以参考[reqPermission标签说明](../quick-start/module-structure.md)
# 应用/组件级配置
在开发应用时,需要配置应用的一些标签,例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。
在开发应用时,需要配置应用的一些标签,例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。图标和标签通常一起配置,可以分为应用图标、应用标签和入口图标、入口标签,分别对应[app.json5配置文件](../quick-start/app-configuration-file.md)[module.json5配置文件](../quick-start/module-configuration-file.md)文件中的icon和label标签。应用图标和标签是在设置应用中使用,例如设置应用中的应用列表。入口图标是应用安装完成后在设备桌面上显示出来的,如图一所示。入口图标是以[UIAbility](uiability-overview.md)为粒度,支持同一个应用存在多个入口图标和标签,点击后进入对应的UIAbility界面
图标和标签通常一起配置,可以分为应用图标、应用标签和入口图标、入口标签,分别对应[app.json5配置文件](../quick-start/app-configuration-file.md)[module.json5配置文件](../quick-start/module-configuration-file.md)文件中的icon和label标签
应用图标和标签是在设置应用中使用,例如设置应用中的应用列表。入口图标是应用安装完成后在设备桌面上显示出来的,如图一所示。入口图标是以[UIAbility](uiability-overview.md)为粒度,支持同一个应用存在多个入口图标和标签,点击后进入对应的UIAbility界面。
**图1** 应用图标和标签  
![application-component-configuration-stage](figures/application-component-configuration-stage.png)
**图1** 应用图标和标签  
![application-component-configuration-stage](figures/application-component-configuration-stage.png)
- **应用包名配置**
......@@ -22,13 +23,13 @@
应用标签需要在工程的AppScope模块下的[app.json5配置文件](../quick-start/app-configuration-file.md)中配置label标签。标识应用对用户显示的名称,需要配置为字符串资源的索引。
```json
{
"app": {
"icon": "$media:app_icon",
"label": "$string:app_name"
// ...
}
{
"app": {
"icon": "$media:app_icon",
"label": "$string:app_name"
...
}
}
```
- **入口图标和标签配置**
......@@ -40,7 +41,7 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// $开头的为资源值
......@@ -71,4 +72,4 @@
- **Module权限配置**
Module访问系统或其他应用受保护部分所需的权限信息需要在[module.json5配置文件](../quick-start/module-configuration-file.md)中配置requestPermission标签。该标签用于声明需要申请权限的名称、申请权限的原因以及权限使用的场景。
\ No newline at end of file
Module访问系统或其他应用受保护部分所需的权限信息需要在[module.json5配置文件](../quick-start/module-configuration-file.md)中配置requestPermission标签。该标签用于声明需要申请权限的名称、申请权限的原因以及权限使用的场景。
......@@ -5,14 +5,12 @@
[Context](../reference/apis/js-apis-inner-application-context.md)是应用中对象的上下文,其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用开发路径)、area(文件分区)等,以及应用的一些基本方法,例如createBundleContext()、getApplicationContext()等。UIAbility组件和各种ExtensionAbility派生类组件都有各自不同的Context类。分别有基类Context、ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionContext、ServiceExtensionContext等Context。
- 各类Context的继承关系
- 各类Context的继承关系
![context-inheritance](figures/context-inheritance.png)
- 各类Context的持有关系
- 各类Context的持有关系
![context-holding](figures/context-holding.png)
- 各类Context的获取方式
- 获取[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)。每个UIAbility中都包含了一个Context属性,提供操作应用组件、获取应用组件的配置信息等能力。
......@@ -21,7 +19,7 @@
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let uiAbilityContext = this.context;
// ...
...
}
}
```
......@@ -36,7 +34,7 @@
export default class MyService extends ServiceExtensionAbility {
onCreate(want) {
let serviceExtensionContext = this.context;
// ...
...
}
}
```
......@@ -47,7 +45,7 @@
export default class MyAbilityStage extends AbilityStage {
onCreate() {
let abilityStageContext = this.context;
// ...
...
}
}
```
......@@ -58,7 +56,7 @@
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
// ...
...
}
}
```
......@@ -85,17 +83,16 @@
| 属性名称 | 参数类型 | 可读 | 可写 | 说明 |
| -------- | -------- | -------- | -------- | -------- |
| bundleCodeDir | string | 是 | 否 | 安装文件路径。应用在内部存储上的安装路径。 |
| cacheDir | string | 是 | 否 | 应用缓存文件路径。应用在内部存储上的缓存路径。<br/>对应于“设置&nbsp;&gt;&nbsp;应用管理”,找到对应应用的“存储”中的缓存内容。 |
| filesDir | string | 是 | 否 | 应用通用文件路径。应用在内部存储上的文件路径。<br/>本目录下存放的文件可能会被应用迁移或者备份的时候同步到其他目录中。 |
| preferencesDir | string | 是 | 是 | 应用首选项文件路径。指示应用程序首选项目录。 |
| tempDir | string | 是 | 否 | 应用临时文件路径。<br/>在应用卸载后,系统会删除存储在此目录中的文件。 |
| cacheDir | string | 是 | 否 | 缓存文件路径。应用在内部存储上的缓存路径。<br/>对应于“设置&nbsp;&gt;&nbsp;应用管理”,找到对应应用的“存储”中的缓存内容。 |
| filesDir | string | 是 | 否 | 通用文件路径。应用在内部存储上的文件路径。<br/>本目录下存放的文件可能会被应用迁移或者备份的时候同步到其他目录中。 |
| preferencesDir | string | 是 | 是 | 首选项文件路径。指示应用程序首选项目录。 |
| tempDir | string | 是 | 否 | 临时文件路径。<br/>在应用卸载后,系统会删除存储在此目录中的文件。 |
| databaseDir | string | 是 | 否 | 数据库路径。获取本地数据库存储路径。 |
| distributedFilesDir | string | 是 | 否 | 应用分布式文件路径。 |
| distributedFilesDir | string | 是 | 否 | 分布式文件路径。 |
获取路径的能力是基类Context中提供的能力,因此在ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext中均可以获取,在各类Context中获取到的路径会有一些差别,具体差别如下图所示。
**图1** Context中获取的应用开发路径
**图1** Context中获取的应用开发路径
![context-dir](figures/context-dir.png)
- 通过ApplicationContext获取的应用级别路径。应用全局信息建议存放的路径,存放在此路径的文件内容仅在应用卸载时会被删除。
......@@ -135,7 +132,7 @@ export default class EntryAbility extends UIAbility {
let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
// ...
...
}
}
```
......@@ -201,7 +198,7 @@ export default class EntryAbility extends UIAbility {
let bundleName2 = 'com.example.application';
let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label;
// ...
...
}
}
```
......@@ -223,7 +220,7 @@ export default class EntryAbility extends UIAbility {
let bundleName2 = 'com.example.application';
let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(bundleName2, moduleName2);
// ...
...
}
}
```
......@@ -237,7 +234,7 @@ export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(moduleName2);
// ...
...
}
}
```
......@@ -265,53 +262,53 @@ export default class EntryAbility extends UIAbility {
let abilityLifecycleCallback = {
// 当UIAbility创建时被调用
onAbilityCreate(uiAbility) {
console.log(TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当窗口创建时被调用
onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
console.info(TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
},
// 当窗口处于活动状态时被调用
onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
console.info(TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
},
// 当窗口处于非活动状态时被调用
onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
console.info(TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
},
// 当窗口被销毁时被调用
onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
console.log(TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.log(TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
console.info(TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
},
// 当UIAbility被销毁时被调用
onAbilityDestroy(uiAbility) {
console.log(TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当UIAbility从后台转到前台时触发回调
onAbilityForeground(uiAbility) {
console.log(TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当UIAbility从前台转到后台时触发回调
onAbilityBackground(uiAbility) {
console.log(TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// 当UIAbility迁移时被调用
onAbilityContinue(uiAbility) {
console.log(TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}
}
// 获取应用上下文
let applicationContext = this.context.getApplicationContext();
// 注册应用内生命周期回调
this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
console.log(TAG, `register callback number: ${this.lifecycleId}`);
console.info(TAG, `register callback number: ${this.lifecycleId}`);
}
// ...
...
onDestroy() {
// 获取应用上下文
......
......@@ -37,7 +37,7 @@ Stage模型之所以成为主推模型,源于其设计思想。Stage模型的
Stage模型重新定义应用能力的边界,平衡应用能力和系统管控成本。
- 提供特定场景(如卡片、输入法)的应用组件,以便满足更多的使用场景。
- 提供特定场景(如服务卡片、输入法)的应用组件,以便满足更多的使用场景。
- 规范化后台进程管理:为保障用户体验,Stage模型对后台应用进程进行了有序治理,应用程序不能随意驻留在后台,同时应用后台行为受到严格管理,防止恶意应用行为。
......@@ -51,7 +51,7 @@ Stage模型之所以成为主推模型,源于其设计思想。Stage模型的
| 项目 | FA模型 | Stage模型 |
| -------- | -------- | -------- |
| **应用组件** | 1.&nbsp;组件分类<br/>![fa-model-component](figures/fa-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;PageAbility组件:包含UI界面,提供展示UI的能力。详细介绍请参见[PageAbility组件概述](pageability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ServiceAbility组件:提供后台服务的能力,无UI界面。详细介绍请参见[ServiceAbility组件概述](serviceability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;DataAbility组件:提供数据分享的能力,无UI界面。详细介绍请参见[DataAbility组件概述](dataability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;通过导出匿名对象、固定入口文件的方式指定应用组件。开发者无法进行派生,不利于扩展能力。 | 1.&nbsp;组件分类<br/>![stage-model-component](figures/stage-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;UIAbility组件:包含UI界面,提供展示UI的能力,主要用于和用户交互。详细介绍请参见[UIAbility组件概述](uiability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ExtensionAbility组件:提供特定场景(如卡片、输入法)的扩展能力,满足更多的使用场景。详细介绍请参见[ExtensionAbility组件概述](extensionability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;采用面向对象的方式,将应用组件以类接口的形式开放给开发者,可以进行派生,利于扩展能力。 |
| **应用组件** | 1.&nbsp;组件分类<br/>![fa-model-component](figures/fa-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;PageAbility组件:包含UI,提供展示UI的能力。详细介绍请参见[PageAbility组件概述](pageability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ServiceAbility组件:提供后台服务的能力,无UI。详细介绍请参见[ServiceAbility组件概述](serviceability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;DataAbility组件:提供数据分享的能力,无UI。详细介绍请参见[DataAbility组件概述](dataability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;通过导出匿名对象、固定入口文件的方式指定应用组件。开发者无法进行派生,不利于扩展能力。 | 1.&nbsp;组件分类<br/>![stage-model-component](figures/stage-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;UIAbility组件:包含UI,提供展示UI的能力,主要用于和用户交互。详细介绍请参见[UIAbility组件概述](uiability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ExtensionAbility组件:提供特定场景(如卡片、输入法)的扩展能力,满足更多的使用场景。详细介绍请参见[ExtensionAbility组件概述](extensionability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;采用面向对象的方式,将应用组件以类接口的形式开放给开发者,可以进行派生,利于扩展能力。 |
| **进程模型** | 有两类进程:<br/>1.&nbsp;主进程<br/>2.&nbsp;渲染进程<br/>详细介绍请参见[进程模型](process-model-fa.md)。 | 有三类进程:<br/>1.&nbsp;主进程<br/>2.&nbsp;ExtensionAbility进程<br/>3.&nbsp;渲染进程<br/>详细介绍请参见[进程模型](process-model-stage.md)。 |
| **线程模型** | 1.&nbsp;ArkTS引擎实例的创建<br/>&nbsp;&nbsp;&nbsp;一个进程可以运行多个应用组件实例,每个应用组件实例运行在一个单独的ArkTS引擎实例中。<br/>2.&nbsp;线程模型<br/>&nbsp;&nbsp;&nbsp;每个ArkTS引擎实例都在一个单独线程(非主线程)上创建,主线程没有ArkTS引擎实例。<br/>3.&nbsp;进程内对象共享:不支持。<br/>详细介绍请参见[线程模型](thread-model-fa.md)。 | 1.&nbsp;ArkTS引擎实例的创建<br/>&nbsp;&nbsp;&nbsp;一个进程可以运行多个应用组件实例,所有应用组件实例共享一个ArkTS引擎实例。<br/>2.&nbsp;线程模型<br/>&nbsp;&nbsp;&nbsp;ArkTS引擎实例在主线程上创建。<br/>3.&nbsp;进程内对象共享:支持。<br/>详细介绍请参见[线程模型](thread-model-stage.md)。 |
| **任务管理模型** | -&nbsp;每个PageAbility组件实例创建一个任务。<br/>-&nbsp;任务会持久化存储,直到超过最大任务个数(根据产品配置自定义)或者用户主动删除任务。<br/>-&nbsp;PageAbility组件之间不会形成栈的结构。<br/>详细介绍请参见[任务管理场景介绍](mission-management-overview.md)。 | -&nbsp;每个UIAbility组件实例创建一个任务。<br/>-&nbsp;任务会持久化存储,直到超过最大任务个数(根据产品配置自定义)或者用户主动删除任务。<br/>-&nbsp;UIAbility组件之间不会形成栈的结构。<br/>详细介绍请参见[任务管理场景介绍](mission-management-overview.md)。 |
......
# 使用方刷新卡片内容(仅对系统应用开放)
当使用方添加了一些周期性刷新的卡片后,由于周期性刷新的时间间隔限制,可以在使用方中提供按钮主动触发卡片的刷新。这种场景下使用方可以通过调用[requestForm](../reference/apis/js-apis-app-form-formHost.md#requestform)接口请求卡片刷新,系统会调用卡片提供方FormExtensionAbility中的[onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform)生命周期回调,在回调中,可以使用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片内容。onUpdateForm生命周期回调参考[通过FormExtensionAbility刷新卡片内容](arkts-ui-widget-event-formextensionability.md)
当使用方添加了一些周期性刷新的卡片后,由于周期性刷新的时间间隔限制,可以在使用方中提供按钮主动触发卡片的刷新。这种场景下使用方可以通过调用[requestForm](../reference/apis/js-apis-app-form-formHost.md#requestform)接口请求卡片刷新,系统会调用卡片提供方FormExtensionAbility中的[onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform)生命周期回调,在回调中,可以使用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片内容。onUpdateForm生命周期回调参考[通过FormExtensionAbility刷新卡片内容](arkts-ui-widget-event-formextensionability.md)
```ts
import formHost from '@ohos.app.form.formHost';
......
......@@ -2,18 +2,15 @@
在已有的应用工程中,创建ArkTS卡片,具体的操作方式如下。
1. 创建卡片。
1. 创建卡片。
![WidgetProjectCreate1](figures/WidgetProjectCreate1.png)
2. 根据实际业务场景,选择一个卡片模板。
2. 根据实际业务场景,选择一个卡片模板。
![WidgetProjectCreate2](figures/WidgetProjectCreate2.png)
3. 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单击“Finish”,即可完成ArkTS卡片创建。
3. 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单击“Finish”,即可完成ArkTS卡片创建。
![WidgetProjectCreate3](figures/WidgetProjectCreate3.png)
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)。
![WidgetProjectView](figures/WidgetProjectView.png)
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)
![WidgetProjectView](figures/WidgetProjectView.png)
\ No newline at end of file
......@@ -52,38 +52,38 @@
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
function FunACall(data) {
// 获取call事件中传递的所有参数
console.log('FunACall param:' + JSON.stringify(data.readString()));
console.info('FunACall param:' + JSON.stringify(data.readString()));
return null;
}
function FunBCall(data) {
console.log('FunACall param:' + JSON.stringify(data.readString()));
console.info('FunACall param:' + JSON.stringify(data.readString()));
return null;
}
export default class CameraAbility extends UIAbility {
// 如果UIAbility第一次启动,在收到call事件后会触发onCreate生命周期回调
onCreate(want, launchParam) {
try {
// 监听call事件所需的方法
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
}
try {
// 监听call事件所需的方法
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
console.error(`Failed to register callee on. Cause: ${JSON.stringify(err)}`);
}
}
// 进程退出时,解除监听
onDestroy() {
try {
this.callee.off('funA');
this.callee.off('funB');
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
}
try {
this.callee.off('funA');
this.callee.off('funB');
} catch (err) {
console.error(`Failed to register callee off. Cause: ${JSON.stringify(err)}`);
}
}
};
```
......@@ -4,7 +4,7 @@
在卡片页面中可以通过**postCardAction**接口触发message事件至FormExtensionAbility,然后由FormExtensionAbility刷新卡片内容,下面是这种刷新方式的简单示例。
- 在卡片页面通过注册Button的onClick点击事件回调,并在回调中调用**postCardAction**接口触发事件至FormExtensionAbility
- 在卡片页面通过注册Button的onClick点击事件回调,并在回调中调用**postCardAction**接口触发事件至FormExtensionAbility
```ts
let storage = new LocalStorage();
......@@ -34,7 +34,7 @@
}
```
- 在FormExtensionAbility的onFormEvent生命周期中调用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片
- 在FormExtensionAbility的onFormEvent生命周期中调用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片
```ts
import formBindingData from '@ohos.app.form.formBindingData';
......@@ -57,10 +57,9 @@
})
}
// ...
...
}
```
运行效果如下图所示。
运行效果如下图所示。
![WidgetUpdatePage](figures/WidgetUpdatePage.png)
# 卡片事件能力说明
ArkTS卡片中提供了postCardAction()接口用于卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件,仅在卡片中可以调用。
ArkTS卡片中提供了postCardAction()接口用于卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件,仅在卡片中可以调用。
![WidgetPostCardAction](figures/WidgetPostCardAction.png)
......@@ -31,9 +28,7 @@ action参数说明:
| "params" | Object | 当前action携带的额外参数,内容使用JSON格式的键值对形式。"call"&nbsp;类型时需填入参数'method',且类型需要为string类型,用于触发UIAbility中对应的方法,必填。 |
postCardAction()接口示例代码:
`postCardAction()`接口示例代码:
```typescript
Button('跳转')
......@@ -49,8 +44,7 @@ Button('跳转')
}
});
})
```
```typescript
Button('拉至后台')
.width('40%')
.height('20%')
......@@ -67,7 +61,6 @@ Button('拉至后台')
})
```
以下是卡片开发过程中可以通过卡片事件实现的典型开发场景:
......
# 使用router事件跳转到指定页面
在卡片中使用**postCardAction**接口的router能力,能够快速拉起卡片提供方应用,因此页面较多的应用往往会通过卡片提供不同的跳转按钮,实现一键直达的效果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机应用的不同页面,从而提高用户的体验。
在卡片中使用**postCardAction**接口的router能力,能够快速拉起卡片提供方应用,因此页面较多的应用往往会通过卡片提供不同的跳转按钮,实现一键直达的效果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机应用的不同页面,从而提高用户的体验。
![WidgerCameraCard](figures/WidgerCameraCard.png)
......
......@@ -89,7 +89,7 @@
## 通过postCardAction接口触发call事件
- 在使用**postCardAction**接口的call事件时,需要在FormExtensionAbility中的onAddForm生命周期回调中更新formId。
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
......@@ -117,7 +117,7 @@
struct WidgetCard {
@LocalStorageProp('detail') detail: string = 'init';
@LocalStorageProp('formId') formId: string = '0';
build() {
Column() {
Button('拉至后台')
......@@ -150,8 +150,8 @@
import formProvider from '@ohos.app.form.formProvider';
import formInfo from '@ohos.app.form.formInfo';
const MSG_SEND_METHOD: string = 'funA'
const MSG_SEND_METHOD: string = 'funA';
// 在收到call事件后会触发callee监听的方法
function FunACall(data) {
// 获取call事件中传递的所有参数
......@@ -180,9 +180,9 @@
// 监听call事件所需的方法
this.callee.on(MSG_SEND_METHOD, FunACall);
} catch (error) {
console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`)
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`)
}
}
...
}
```
\ No newline at end of file
```
......@@ -160,7 +160,7 @@
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> - Image组件通过入参(**memory://fileName**)中的**memory://**标识来进行远端内存图片显示,其中**fileName**需要和EntryFormAbility传递对象(**'formImages': {key: fd})**中的**key**相对应。
>
> - Image组件通过传入的参数是否有变化来决定是否刷新图片,因此EntryFormAbility每次传递过来的**imgName**都需要不同,连续传递两个相同的**imgName**时,图片不会刷新。
# 卡片数据交互说明
ArkTS卡片框架提供了updateForm()接口和requestForm()接口主动触发卡片的页面刷新。
ArkTS卡片框架提供了updateForm()接口和requestForm()接口主动触发卡片的页面刷新。
![WidgetLocalStorageProp](figures/WidgetLocalStorageProp.png)
......@@ -17,4 +14,4 @@ ArkTS卡片框架提供了updateForm()接口和requestForm()接口主动触发
- [定时刷新和定点刷新](arkts-ui-widget-update-by-time.md)
- [刷新本地图片和网络图片](arkts-ui-widget-image-update.md)
- [根据卡片状态刷新不同内容](arkts-ui-widget-update-by-status.md)
- [使用方刷新卡片内容(仅对系统应用开放)](arkts-ui-widget-content-update.md)
\ No newline at end of file
- [使用方刷新卡片内容(仅对系统应用开放)](arkts-ui-widget-content-update.md)
......@@ -91,5 +91,6 @@
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> FormExtensionAbility进程不能常驻后台,即在卡片生命周期回调函数中无法处理长时间的任务,在生命周期调度完成后会继续存在5秒,如5秒内没有新的生命周期回调触发则进程自动退出。针对可能需要5秒以上才能完成的业务逻辑,建议[拉起主应用](arkts-ui-widget-event-uiability.md)进行处理,处理完成后使用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)通知卡片进行刷新。
> **说明:**
>
> FormExtensionAbility进程不能常驻后台,即在卡片生命周期回调函数中无法处理长时间的任务,在生命周期调度完成后会继续存在5秒,如5秒内没有新的生命周期回调触发则进程自动退出。针对可能需要5秒以上才能完成的业务逻辑,建议[拉起主应用](arkts-ui-widget-event-uiability.md)进行处理,处理完成后使用[`updateForm()`](../reference/apis/js-apis-app-form-formProvider.md#updateform)通知卡片进行刷新。
# ArkTS卡片相关模块
**图1** ArkTS卡片相关模块  
**图1** ArkTS卡片相关模块
![WidgetModules](figures/WidgetModules.png)
......
......@@ -4,7 +4,7 @@
ArkTS卡片开放了使用动画效果的能力,支持[显式动画](../reference/arkui-ts/ts-explicit-animation.md)[属性动画](../reference/arkui-ts/ts-animatorproperty.md)[组件内转场](../reference/arkui-ts/ts-transition-animation-component.md)能力。需要注意的是,ArkTS卡片使用动画效果时具有以下限制:
**表1** 动效参数限制
**表1** 动效参数限制
| 名称 | 参数说明 | 限制描述 |
| -------- | -------- | -------- |
......@@ -13,10 +13,7 @@ ArkTS卡片开放了使用动画效果的能力,支持[显式动画](../refere
| delay | 动画延迟执行的时长 | 卡片中禁止设置此参数,使用默认值0。 |
| iterations | 动画播放次数 | 卡片中禁止设置此参数,使用默认值1。 |
以下示例代码实现了按钮旋转的动画效果:
以下示例代码实现了按钮旋转的动画效果:
![WidgetAnimation](figures/WidgetAnimation.gif)
......
# 卡片使用自定义绘制能力
ArkTS卡片开放了自定义绘制的能力,在卡片上可以通过[Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md)组件创建一块画布,然后通过[CanvasRenderingContext2D](../reference/arkui-ts/ts-canvasrenderingcontext2d.md)对象在画布上进行自定义图形的绘制,如下示例代码实现了在画布的中心绘制了一个笑脸。
ArkTS卡片开放了自定义绘制的能力,在卡片上可以通过[Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md)组件创建一块画布,然后通过[CanvasRenderingContext2D](../reference/arkui-ts/ts-canvasrenderingcontext2d.md)对象在画布上进行自定义图形的绘制,如下示例代码实现了在画布的中心绘制了一个笑脸。
```typescript
```ts
@Entry
@Component
struct Card {
......@@ -30,41 +30,41 @@ struct Card {
this.context.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
// 在画布的中心绘制一个红色的圆
this.context.beginPath();
let radius = this.context.width / 3
let circleX = this.context.width / 2
let circleY = this.context.height / 2
let radius = this.context.width / 3;
let circleX = this.context.width / 2;
let circleY = this.context.height / 2;
this.context.moveTo(circleX - radius, circleY);
this.context.arc(circleX, circleY, radius, 2 * Math.PI, 0, true);
this.context.closePath();
this.context.fillStyle = 'red';
this.context.fill();
// 绘制笑脸的左眼
let leftR = radius / 4
let leftX = circleX - (radius / 2)
let leftY = circleY - (radius / 3.5)
let leftR = radius / 4;
let leftX = circleX - (radius / 2);
let leftY = circleY - (radius / 3.5);
this.context.beginPath();
this.context.arc(leftX, leftY, leftR, 0, Math.PI, true);
this.context.strokeStyle = '#ffff00'
this.context.lineWidth = 10
this.context.stroke()
this.context.strokeStyle = '#ffff00';
this.context.lineWidth = 10;
this.context.stroke();
// 绘制笑脸的右眼
let rightR = radius / 4
let rightX = circleX + (radius / 2)
let rightY = circleY - (radius / 3.5)
let rightR = radius / 4;
let rightX = circleX + (radius / 2);
let rightY = circleY - (radius / 3.5);
this.context.beginPath();
this.context.arc(rightX, rightY, rightR, 0, Math.PI, true);
this.context.strokeStyle = '#ffff00'
this.context.lineWidth = 10
this.context.stroke()
this.context.strokeStyle = '#ffff00';
this.context.lineWidth = 10;
this.context.stroke();
// 绘制笑脸的嘴巴
let mouthR = radius / 2.5
let mouthX = circleX
let mouthY = circleY + (radius / 3)
let mouthR = radius / 2.5;
let mouthX = circleX;
let mouthY = circleY + (radius / 3);
this.context.beginPath();
this.context.arc(mouthX, mouthY, mouthR, Math.PI, 0, true);
this.context.strokeStyle = '#ffff00'
this.context.lineWidth = 10
this.context.stroke()
this.context.strokeStyle = '#ffff00';
this.context.lineWidth = 10;
this.context.stroke();
})
}
}.height('100%').width('100%')
......@@ -72,8 +72,5 @@ struct Card {
}
```
运行效果如下图所示。
![WidgetCanvasDemo](figures/WidgetCanvasDemo.jpeg)
运行效果如下图所示。
![WidgetCanvasDemo](figures/WidgetCanvasDemo.png)
# 卡片页面能力说明
开发者可以使用声明式范式开发ArkTS卡片页面。如下卡片页面由DevEco Studio模板自动生成,开发者可以根据自身的业务场景进行调整。
开发者可以使用声明式范式开发ArkTS卡片页面。如下卡片页面由DevEco Studio模板自动生成,开发者可以根据自身的业务场景进行调整。
![WidgetPreviewPage](figures/WidgetPreviewPage.png)
......@@ -16,7 +13,6 @@ ArkTS卡片支持的页面能力详见[学习ArkTS语言](../quick-start/arkts-c
只有标识“支持在ArkTS卡片中使用”的接口可用于ArkTS卡片,同时请留意卡片场景下的能力差异说明。
例如:以下说明表示@Component装饰器可在ArkTS卡片中使用。
例如:以下说明表示@Component装饰器可在ArkTS卡片中使用。
![WidgetSupportApi](figures/WidgetSupportApi.png)
......@@ -166,6 +166,7 @@
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
>
> 通过本地数据库进行卡片信息的持久化时,建议先在[**onAddForm**](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform)生命周期中通过[**TEMPORARY_KEY**](../reference/apis/js-apis-app-form-formInfo.md#formparam)判断当前添加的卡片是否为常态卡片:如果是常态卡片,则直接进行卡片信息持久化;如果为临时卡片,则可以在卡片转为常态卡片(**[onCastToNormalForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#oncasttonormalform)**)时进行持久化;同时需要在卡片销毁(**[onRemoveForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onremoveform)**)时删除当前卡片存储的持久化信息,避免反复添加删除卡片导致数据库文件持续变大。
......@@ -5,11 +5,11 @@
当前卡片框架提供了如下几种按时间刷新卡片的方式:
- 定时刷新:表示在一定时间间隔内自动刷新卡片内容。可以在form_config.json配置文件的[updateDuration](arkts-ui-widget-configuration.md)字段中进行设置。例如,可以将刷新时间设置为每小时一次。
- 定时刷新:表示在一定时间间隔内自动刷新卡片内容。可以在form_config.json配置文件的[`updateDuration`](arkts-ui-widget-configuration.md)字段中进行设置。例如,可以将刷新时间设置为每小时一次。
> **说明:**
>
> 当配置了updateDuration(定时刷新)后,该设置会优先于scheduledUpdateTime(定点刷新)生效,即使同时配置了两者,定点刷新也会被忽略。
> 当配置了`updateDuration`(定时刷新)后,该设置会优先于`scheduledUpdateTime`(定点刷新)生效,即使同时配置了两者,定点刷新也会被忽略。
```json
{
......@@ -35,11 +35,11 @@
}
```
- 定点刷新:表示在每天的某个特定时间点自动刷新卡片内容。可以在form_config.jso配置文件中的[scheduledUpdateTime](arkts-ui-widget-configuration.md)字段中进行设置。例如,可以将刷新时间设置为每天的上午10点30分。
- 定点刷新:表示在每天的某个特定时间点自动刷新卡片内容。可以在form_config.json配置文件中的[`scheduledUpdateTime`](arkts-ui-widget-configuration.md)字段中进行设置。例如,可以将刷新时间设置为每天的上午10点30分。
> **说明:**
>
> 当同时配置了定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)时,定时刷新的优先级更高。如果想要配置定点刷新,则需要将updateDuration配置为0。
> 当同时配置了定时刷新(`updateDuration`)和定点刷新(`scheduledUpdateTime`)时,定时刷新的优先级更高。如果想要配置定点刷新,则需要将`updateDuration`配置为0。
```json
......@@ -88,11 +88,11 @@
```
在触发定时、定点或主动刷新后,系统会调用FormExtensionAbility的[onUpdateForm()](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform)生命周期回调,在回调中,可以使用[updateForm()](../reference/apis/js-apis-app-form-formProvider.md#updateform)进行提供方刷新卡片。onUpdateForm()生命周期回调参考[通过FormExtensionAbility刷新卡片内容](arkts-ui-widget-event-formextensionability.md)
在触发定时、定点或下次刷新后,系统会调用FormExtensionAbility的[`onUpdateForm()`](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform)生命周期回调,在回调中,可以使用[`updateForm()`](../reference/apis/js-apis-app-form-formProvider.md#updateform)进行提供方刷新卡片。`onUpdateForm()`生命周期回调的使用请参见[通过FormExtensionAbility刷新卡片内容](arkts-ui-widget-event-formextensionability.md)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 1. 定时刷新有配额限制,每张卡片每天最多通过定时方式触发刷新50次,定时刷新包含[卡片配置项updateDuration](arkts-ui-widget-configuration.md)和调用[setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime)方法两种方式,当达到50次配额后,无法通过定时方式再次触发刷新,刷新次数会在每天的0点重置。
> **说明:**
> 1. 定时刷新有配额限制,每张卡片每天最多通过定时方式触发刷新50次,定时刷新包含[卡片配置项updateDuration](arkts-ui-widget-configuration.md)和调用[`setFormNextRefreshTime()`](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime)方法两种方式,当达到50次配额后,无法通过定时方式再次触发刷新,刷新次数会在每天的0点重置。
>
> 2. 当前定时刷新使用同一个计时器进行计时,因此卡片定时刷新的第一次刷新会有最多30分钟的偏差。比如第一张卡片A(每隔半小时刷新一次)在3点20分添加成功,定时器启动并每隔半小时触发一次事件,第二张卡片B(每隔半小时刷新一次)在3点40分添加成功,在3点50分定时器事件触发时,卡片A触发定时刷新,卡片B会在下次事件(4点20分)中才会触发。
>
......
......@@ -3,7 +3,7 @@
## 实现原理
**图1** ArkTS卡片实现原理  
**图1** ArkTS卡片实现原理
![WidgetPrinciple](figures/WidgetPrinciple.png)
- 卡片使用方:显示卡片内容的宿主应用,控制卡片在宿主中展示的位置,当前仅系统应用可以作为卡片使用方。
......@@ -14,7 +14,7 @@
- 卡片渲染服务:用于管理卡片渲染实例,渲染实例与卡片使用方上的[卡片组件](../reference/arkui-ts/ts-basic-components-formcomponent.md)一一绑定。卡片渲染服务运行卡片页面代码widgets.abc进行渲染,并将渲染后的数据发送至卡片使用方对应的[卡片组件](../reference/arkui-ts/ts-basic-components-formcomponent.md)
**图2** ArkTS卡片渲染服务运行原理  
**图2** ArkTS卡片渲染服务运行原理
![WidgetRender](figures/WidgetRender.png)
与JS卡片相比,ArkTS卡片支持在卡片中运行逻辑代码,为确保ArkTS卡片发生问题后不影响卡片使用方应用的使用,ArkTS卡片新增了卡片渲染服务用于运行卡片页面代码widgets.abc,卡片渲染服务由卡片管理服务管理。卡片使用方的每个卡片组件都对应了卡片渲染服务里的一个渲染实例,同一应用提供方的渲染实例运行在同一个虚拟机运行环境中,不同应用提供方的渲染实例运行在不同的虚拟机运行环境中,通过虚拟机运行环境隔离不同应用提供方卡片之间的资源与状态。开发过程中需要注意的是[globalThis](uiability-data-sync-with-ui.md#使用globalthis进行数据同步)对象的使用,相同应用提供方的卡片globalThis对象是同一个,不同应用提供方的卡片globalThis对象是不同的。
......@@ -25,11 +25,12 @@
卡片作为应用的一个快捷入口,ArkTS卡片相较于JS卡片具备如下几点优势:
- 统一开发范式,提升开发体验和开发效率。
OpenHarmony在2022年发布了声明式范式的UI开发框架,而卡片还延续了css/hml/json三段式类Web范式的开发方式,提高了开发者的学习成本,提供ArkTS卡片能力后,统一了卡片和页面的开发范式,页面的布局可以直接复用到卡片布局中,提升开发体验和开发效率。
**图3** 卡片工程结构对比  
**图3** 卡片工程结构对比
![WidgetProject](figures/WidgetProject.png)
- 增强了卡片的能力,使卡片更加万能。
- 新增了动效的能力:ArkTS卡片开放了[属性动画](../reference/arkui-ts/ts-animatorproperty.md)[显式动画](../reference/arkui-ts/ts-explicit-animation.md)的能力,使卡片的交互更加友好。
- 新增了自定义绘制的能力:ArkTS卡片开放了[Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md)画布组件,卡片可以使用自定义绘制的能力构建更多样的显示和交互效果。
......
......@@ -12,15 +12,15 @@ UIAbility关联访问ServiceAbility和UIAbility关联访问ServiceExtensionAbili
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends UIAbility {
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
console.info("MainAbility onCreate");
console.info("EntryAbility onCreate");
}
onDestroy() {
console.info("MainAbility onDestroy")
console.info("EntryAbility onDestroy")
}
onWindowStageCreate(windowStage) {
console.info("MainAbility onWindowStageCreate")
console.info("EntryAbility onWindowStageCreate")
let want = {
bundleName: "com.ohos.fa",
abilityName: "ServiceAbility",
......@@ -40,13 +40,13 @@ export default class MainAbility extends UIAbility {
let connectionId = this.context.connectServiceExtensionAbility(want, options);
}
onWindowStageDestroy() {
console.info("MainAbility onWindowStageDestroy")
console.info("EntryAbility onWindowStageDestroy")
}
onForeground() {
console.info("MainAbility onForeground")
console.info("EntryAbility onForeground")
}
onBackground() {
console.info("MainAbility onBackground")
console.info("EntryAbility onBackground")
}
}
```
......
......@@ -19,11 +19,10 @@ OpenHarmony通过CES(Common Event Service,公共事件服务)为应用程
- 有序公共事件:CES转发公共事件时,根据订阅者设置的优先级等级,在接收到优先级较高的一个订阅者回复后,再向下一个优先级较低的订阅者转发公共事件。具有相同优先级的订阅者将按随机顺序收到公共事件。
- 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请`ohos.permission.COMMONEVENT_STICKY`权限,配置方式请参见[访问控制授权申请](../security/accesstoken-guidelines.md#配置文件权限声明)
- 粘性公共事件:能够让订阅者收到在订阅前已经发送的公共事件就是粘性公共事件。普通的公共事件只能在订阅后发送才能收到,而粘性公共事件的特殊性就是可以先发送后订阅,同时也支持先订阅后发送。发送粘性事件必须是系统应用或系统服务,粘性事件发送后会一直存在系统中,且发送者需要申请`ohos.permission.COMMONEVENT_STICKY`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
每个应用都可以按需订阅公共事件,订阅成功,当公共事件发布时,系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。
**图1** 公共事件示意图
**图1** 公共事件示意图
![common-event](figures/common-event.png)
......@@ -3,15 +3,15 @@
## 场景介绍
当需要发布某个自定义公共事件时,可以通过publish()方法发布事件。发布的公共事件可以携带数据,供订阅者解析并进行下一步处理。
当需要发布某个自定义公共事件时,可以通过[publish()](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerpublish)方法发布事件。发布的公共事件可以携带数据,供订阅者解析并进行下一步处理。
> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:**
> **须知:**
> 已发出的粘性公共事件后来订阅者也可以接收到,其他公共事件都需要先订阅再接收,订阅参考[公共事件订阅章节](common-event-subscription.md)。
## 接口说明
详细接口见[接口文档](../reference/apis/js-apis-commonEvent.md#commoneventpublish)
详细接口见[接口文档](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerpublish)
| 接口名 | 接口描述 |
| -------- | -------- |
......@@ -23,17 +23,17 @@
不携带信息的公共事件,只能发布无序公共事件。
1. 导入CommonEvent模块。
1. 导入模块。
```ts
import commonEvent from '@ohos.commonEventManager';
import commonEventManager from '@ohos.commonEventManager';
```
2. 传入需要发布的事件名称和回调函数,发布事件。
```ts
// 发布公共事件
commonEvent.publish("usual.event.SCREEN_OFF", (err) => {
commonEventManager.publish("usual.event.SCREEN_OFF", (err) => {
if (err) {
console.error(`[CommonEvent] PublishCallBack err=${JSON.stringify(err)}`);
} else {
......@@ -47,10 +47,10 @@
携带信息的公共事件,可以发布为无序公共事件、有序公共事件和粘性事件,可以通过参数[CommonEventPublishData](../reference/apis/js-apis-commonEventManager.md#commoneventpublishdata)的isOrdered、isSticky的字段进行设置。
1. 导入CommonEvent模块。
1. 导入模块。
```ts
import commonEvent from '@ohos.commonEventManager';
import commonEventManager from '@ohos.commonEventManager';
```
2. 传入需要发布的事件名称和回调函数,发布事件。
......@@ -67,7 +67,7 @@
```ts
// 发布公共事件
commonEvent.publish("usual.event.SCREEN_OFF", options, (err) => {
commonEventManager.publish("usual.event.SCREEN_OFF", options, (err) => {
if (err) {
console.error('[CommonEvent] PublishCallBack err=' + JSON.stringify(err));
} else {
......
......@@ -4,28 +4,24 @@
静态订阅者在未接收订阅的目标事件时,处于未拉起状态,当系统或应用发布了指定的公共事件后,静态订阅者将被拉起,并执行onReceiveEvent回调,开发者可通过在onReceiveEvent回调中执行业务逻辑,实现当应用接收到特定公共事件时执行业务逻辑的目的。例如,某应用希望在设备开机的时候执行一些初始化任务,那么该应用可以静态订阅开机事件,在收到开机事件后会拉起该应用,然后执行初始化任务。静态订阅是通过配置文件声明和实现继承自StaticSubscriberExtensionAbility的类实现对公共事件的订阅。**需要注意的是,静态订阅公共事件对系统功耗有一定影响,建议谨慎使用**
## 开发步骤
1. 静态订阅者声明
声明一个静态订阅者,首先需要在工程中新建一个ExtensionAbility, 该ExtensionAbility从StaticSubscriberExtensionAbility派生,其代码实现如下:
声明一个静态订阅者,首先需要在工程中新建一个ExtensionAbility该ExtensionAbility从StaticSubscriberExtensionAbility派生,其代码实现如下:
```ts
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
onReceiveEvent(event) {
console.info('onReceiveEvent, event:' + event.event);
}
}
```
开发者可以在onReceiveEvent中实现业务逻辑。
2. 静态订阅者工程配置
在完成静态订阅者的代码实现后,需要将该订阅者配置到系统的module.json5中,配置形式如下:
......@@ -33,11 +29,11 @@
```ts
{
"module": {
......
...
"extensionAbilities": [
{
"name": "StaticSubscriber",
"srcEnty": "./ets/StaticSubscriber/StaticSubscriber.ts",
"srcEntry": "./ets/StaticSubscriber/StaticSubscriber.ts",
"description": "$string:StaticSubscriber_desc",
"icon": "$media:icon",
"label": "$string:StaticSubscriber_label",
......@@ -51,14 +47,14 @@
]
}
]
......
...
}
}
```
上述json文件主要关注以下字段:
- srcEnty : 表示ExtensionAbility的入口文件路径,即步骤2中声明的静态订阅者所在的文件路径
- srcEntry : 表示ExtensionAbility的入口文件路径,即步骤2中声明的静态订阅者所在的文件路径
- type: 表示ExtensionAbility的类型,对于静态订阅者需要声明为“staticSubscriber”
......@@ -92,13 +88,21 @@
3. 修改设备系统配置文件
修改设备系统配置文件 **/etc/static_subscriber_config.json**,将静态订阅应用者的包名添加至该json文件中即可。
修改设备系统配置文件 **/system/etc/app/install_list_capability.json**,将静态订阅应用者的包名添加至该json文件中即可。
```json
{
"xxx",
"ohos.extension.staticSubscriber",
"xxx"
{
"install_list": [
{
"bundleName": "ohos.extension.staticSubscriber",
"allowCommonEvent": ["usual.event.A", "usual.event.B"],
}
]
}
```
```
## 相关示例
针对StaticSubscriberExtensionAbility开发,可参考如下实例:
- [StaticSubscriber:静态订阅(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/StaticSubscriber)
# 公共事件订阅概述
公共事件服务提供了动态订阅和静态订阅两种订阅方式。动态订阅与静态订阅最大的区别在于,动态订阅是应用运行时行为,而静态订阅是后台服务无需处于运行状态。
公共事件服务提供了动态订阅和静态订阅两种订阅方式。动态订阅与静态订阅最大的区别在于,动态订阅是应用运行时行为,而静态订阅是后台服务无需处于运行状态。
- 动态订阅:指订阅方在运行时调用公共事件订阅的API实现对公共事件的订阅,详见[动态订阅公共事件](common-event-subscription.md)
- 动态订阅:指订阅方在运行时调用公共事件订阅的API实现对公共事件的订阅,详细请参[动态订阅公共事件](common-event-subscription.md)
- 静态订阅:订阅方通过配置文件声明和实现继承自StaticSubscriberExtensionAbility的类实现对公共事件的订阅,详见[静态订阅公共事件](common-event-static-subscription.md)
\ No newline at end of file
- 静态订阅:订阅方通过配置文件声明和实现继承自StaticSubscriberExtensionAbility的类实现对公共事件的订阅,详细请参见[静态订阅公共事件](common-event-static-subscription.md)
......@@ -8,21 +8,21 @@
## 接口说明
详细接口见[接口文档](../reference/apis/js-apis-commonEvent.md#commoneventcreatesubscriber)
详细接口见[接口文档](../reference/apis/js-apis-commonEventManager.md#commoneventmanagersubscribe)
| 接口名 | 接口描述 |
| -------- | -------- |
| createSubscriber(subscribeInfo:&nbsp;[CommonEventSubscribeInfo](../reference/apis/js-apis-commonEventManager.md#commoneventsubscribeinfo),&nbsp;callback:&nbsp;AsyncCallback&lt;[CommonEventData](../reference/apis/js-apis-commonEventManager.md#commoneventdata)&gt;):&nbsp;void | 创建订阅者对象(callback) |
| createSubscriber(subscribeInfo:&nbsp;CommonEventSubscribeInfo):&nbsp;Promise&lt;CommonEventSubscriber&gt; | 创建订阅者对象(promise) |
| createSubscriber(subscribeInfo:&nbsp;[CommonEventSubscribeInfo](../reference/apis/js-apis-commonEventManager.md#commoneventsubscribeinfo),&nbsp;callback:&nbsp;AsyncCallback&lt;[CommonEventData](../reference/apis/js-apis-commonEventManager.md#commoneventdata)&gt;):&nbsp;void | 创建订阅者对象(callback) |
| createSubscriber(subscribeInfo:&nbsp;CommonEventSubscribeInfo):&nbsp;Promise&lt;CommonEventSubscriber&gt; | 创建订阅者对象(promise) |
| subscribe(subscriber:&nbsp;CommonEventSubscriber,&nbsp;callback:&nbsp;AsyncCallback):&nbsp;void | 订阅公共事件 |
## 开发步骤
1. 导入CommonEvent模块。
1. 导入模块。
```ts
import commonEvent from '@ohos.commonEventManager';
import commonEventManager from '@ohos.commonEventManager';
```
2. 创建订阅者信息,详细的订阅者信息数据类型及包含的参数请见[CommonEventSubscribeInfo](../reference/apis/js-apis-commonEventManager.md#commoneventsubscribeinfo)文档介绍。
......@@ -32,7 +32,7 @@
let subscriber = null;
// 订阅者信息
let subscribeInfo = {
events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
}
```
......@@ -40,14 +40,14 @@
```ts
// 创建订阅者回调
commonEvent.createSubscriber(subscribeInfo, (err, data) => {
if (err) {
console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] CreateSubscriber success`);
subscriber = data;
// 订阅公共事件回调
}
commonEventManager.createSubscriber(subscribeInfo, (err, data) => {
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;
// 订阅公共事件回调
})
```
......@@ -56,14 +56,13 @@
```ts
// 订阅公共事件回调
if (subscriber !== null) {
commonEvent.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`);
}
})
commonEventManager.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`Failed to subscribe common event. Code is ${err.code}, message is ${err.message}`);
return;
}
})
} else {
console.error(`[CommonEvent] Need create subscriber`);
console.error(`Need create subscriber`);
}
```
......@@ -15,25 +15,25 @@
## 开发步骤
1. 导入CommonEvent模块。
1. 导入模块。
```ts
import commonEvent from '@ohos.commonEventManager';
import commonEventManager from '@ohos.commonEventManager';
```
2. 根据[动态订阅公共事件](common-event-subscription.md)章节的步骤来订阅某个事件。
3. 调用CommonEvent中的unsubscribe方法取消订阅某事件。
3. 调用CommonEvent中的unsubscribe()方法取消订阅某事件。
```ts
// subscriber为订阅事件时创建的订阅者对象
if (subscriber !== null) {
commonEvent.unsubscribe(subscriber, (err) => {
commonEventManager.unsubscribe(subscriber, (err) => {
if (err) {
console.error(`[CommonEvent] UnsubscribeCallBack err=${JSON.stringify(err)}`)
console.error(`[CommonEvent] UnsubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] Unsubscribe`)
subscriber = null
console.info(`[CommonEvent] Unsubscribe`);
subscriber = null;
}
})
}
......
......@@ -38,7 +38,7 @@
- 只有系统预置应用才允许配置AssociateWakeUp字段,其余应用AssociateWakeUp默认为**false**
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 1. 组件启动管控自OpenHarmony v3.2 Release版本开始落地。
>
> 2. 与原本的启动规则不同,新的组件启动规则较为严格,开发者需熟知启动规则,避免业务功能异常。
......
......@@ -23,8 +23,8 @@
- **跨应用启动组件,需校验目标组件Visible**
- 若目标组件visible字段配置为false,则需校验`ohos.permission.START_INVISIBLE_ABILITY`权限
- [组件visible配置参考](../quick-start/module-configuration-file.md#abilities标签)
- 若目标组件exported字段配置为false,则需校验`ohos.permission.START_INVISIBLE_ABILITY`权限
- [组件exported配置参考](../quick-start/module-configuration-file.md#abilities标签)
- **位于后台的应用,启动组件需校验BACKGROUND权限**
- 应用前后台判断标准:若应用进程获焦或所属的UIAbility位于前台则判定为前台应用,否则为后台应用
......@@ -34,7 +34,7 @@
- 需校验`ohos.permission.ABILITY_BACKGROUND_COMMUNICATION`权限
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 1. 组件启动管控自OpenHarmony v3.2 Release版本开始落地。
>
> 2. 与原本的启动规则不同,新的组件启动规则较为严格,开发者需熟知启动规则,避免业务功能异常。
......
# Stage模型应用配置文件
应用配置文件中包含应用配置信息、应用组件信息、权限信息、开发者自定义信息等,这些信息在编译构建、分发和运行解决分别提供给编译工具、应用市场和操作系统使用。
在基于Stage模型开发的应用项目代码下,都存在app.json5(一个)及module.json5(一个或多个)两种配置文件,常用配置项请参见[应用/组件级配置](application-component-configuration-stage.md)。对于这两种配置文件的更多介绍,请参见[应用配置文件概述(Stage模型)](../quick-start/application-configuration-file-overview-stage.md)
\ No newline at end of file
......@@ -30,7 +30,7 @@ export default {
```
PageAbility创建成功后,其abilities相关的配置项在config.json中体现,一个名字为MainAbility的config.json配置文件示例如下:
PageAbility创建成功后,其abilities相关的配置项在config.json中体现,一个名字为EntryAbility的config.json配置文件示例如下:
```json
{
......@@ -48,13 +48,13 @@ PageAbility创建成功后,其abilities相关的配置项在config.json中体
],
"orientation": "unspecified",
"visible": true,
"srcPath": "MainAbility",
"name": ".MainAbility",
"srcPath": "EntryAbility",
"name": ".EntryAbility",
"srcLanguage": "ets",
"icon": "$media:icon",
"description": "$string:MainAbility_desc",
"description": "$string:EntryAbility_desc",
"formsEnabled": false,
"label": "$string:MainAbility_label",
"label": "$string:EntryAbility_label",
"type": "page",
"launchType": "singleton"
}
......
......@@ -48,9 +48,9 @@ function implicitStartAbility() {
}
}
context.startAbility(wantInfo).then(() => {
// ...
...
}).catch((err) => {
// ...
...
})
}
```
......@@ -67,7 +67,7 @@ function implicitStartAbility() {
- `ability.picker.fileNames``ability.picker.fileSizes`是数组,两者一一对应。
效果示意如下图所示。
![stage-want2](figures/stage-want2.png)
![](figures/ability-startup-with-implicit-want2.png)
## 被分享方
......@@ -76,17 +76,17 @@ function implicitStartAbility() {
```json
{
"module": {
// ...
...
"abilities": [
{
// ...
...
"skills": [
{
// ...
...
"actions": [
"action.system.home",
"ohos.want.action.sendData"
// ...
...
],
"uris": [
{
......@@ -101,7 +101,7 @@ function implicitStartAbility() {
}
```
当用户选择分享的应用后,嵌套在`ability.want.params.INTENT`字段中的Want参数将会传递给所选应用。被分享方的UIAbility被启动后,可以在其[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)或者[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant)回调中获取传入的Want参数信息。
当用户选择分享的应用后,嵌套在`ability.want.params.INTENT`字段中的Want参数将会传递给所选应用。被分享方的UIAbility被启动后,可以在其[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)或者[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant)回调中获取传入的Want参数信息。
获取到的Want参数信息示例如下,可以使用被分享文件的文件描述符(FD)进行相应操作。
......@@ -129,4 +129,4 @@ function implicitStartAbility() {
},
"entities": []
}
```
\ No newline at end of file
```
......@@ -23,7 +23,7 @@ URI示例:
- 本地设备:dataability:///_com.domainname.dataability.persondata_/_person_/_1_
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 本地设备的"device_id"字段为空,因此在"dataability:"后面有三个"/"。
......
......@@ -61,7 +61,7 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil
};
```
​ 4.在工程Module对应的[module.json5](../quick-start/module-configuration-file.md)配置文件中注册ServiceExtensionAbility,type标签需要设置为“enterpriseAdmin”,srcEnty标签表示当前ExtensionAbility组件所对应的代码路径。
​ 4.在工程Module对应的[module.json5](../quick-start/module-configuration-file.md)配置文件中注册ServiceExtensionAbility,type标签需要设置为“enterpriseAdmin”,srcEntry标签表示当前ExtensionAbility组件所对应的代码路径。
```ts
"extensionAbilities": [
......@@ -69,7 +69,7 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil
"name": "ohos.samples.enterprise_admin_ext_ability",
"type": "enterpriseAdmin",
"exported": true,
"srcEnty": "./ets/enterpriseextability/EnterpriseAdminAbility.ts"
"srcEntry": "./ets/enterpriseextability/EnterpriseAdminAbility.ts"
}
]
```
......
......@@ -9,7 +9,7 @@ ExtensionAbility组件是基于特定场景(例如服务卡片、输入法等
- [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md):FORM类型的ExtensionAbility组件,用于提供服务卡片场景相关能力。
- [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md):WORK_SCHEDULER类型的ExtensionAbility组件,用于提供延迟任务注册、取消、查询的能力。
- [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md):WORK_SCHEDULER类型的ExtensionAbility组件,用于提供延迟任务回调实现的能力。
- [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md):INPUT_METHOD类型的ExtensionAbility组件,用于开发输入法应用。
......@@ -32,14 +32,14 @@ ExtensionAbility组件是基于特定场景(例如服务卡片、输入法等
>
> 3. 三方应用只能使用当前系统已定义的上述类型的ExtensionAbility。
## 使用指定类型的ExtensionAbility组件
所有类型的ExtensionAbility组件均不能被应用直接启动,而是由相应的系统管理服务拉起,以确保其生命周期受系统管控,使用时拉起,使用完销毁。ExtensionAbility组件的调用方无需关心目标ExtensionAbility组件的生命周期。
[InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md)组件为例进行说明,如下图所示,调用方应用发起对InputMethodExtensionAbility组件的调用,此时将先调用输入法管理服务,由输入法管理服务拉起[InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md)组件,返回给调用方,同时开始管理其生命周期。
**图1** 使用InputMethodExtensionAbility组件
**图1** 使用InputMethodExtensionAbility组件
![ExtensionAbility-start](figures/ExtensionAbility-start.png)
......@@ -47,12 +47,11 @@ ExtensionAbility组件是基于特定场景(例如服务卡片、输入法等
以实现卡片[FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md)为例进行说明。卡片框架提供了[FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md)基类,开发者通过派生此基类(如MyFormExtensionAbility),实现回调(如创建卡片的onCreate()回调、更新卡片的onUpdateForm()回调等)来实现具体卡片功能,具体见开发指导见[服务卡片FormExtensionAbility](service-widget-overview.md)
卡片FormExtensionAbility实现方不用关心使用方何时去请求添加、删除卡片,FormExtensionAbility实例及其所在的ExtensionAbility进程的整个生命周期,都是由卡片管理系统服务FormManagerService进行调度管理。
卡片FormExtensionAbility实现方不用关心使用方何时去请求添加、删除卡片,FormExtensionAbility实例及其所在的ExtensionAbility进程的整个生命周期,都是由卡片管理系统服务FormManagerService进行调度管理。
![form_extension](figures/form_extension.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 同一应用内的所有同类型的ExtensionAbility运行在同一独立进程(除ServiceExtensionAbility、DataShareExtensionAbility外),跟UIAbility组件不在同一进程,Stage模型的进程模型请参见[进程模型](process-model-stage.md)。
>
> 例如一个应用有1个UIAbility组件、1个ServiceExtensionAbility、1个DataShareExtensionAbility、2个FormExtensionAbility、1个ImeExtensionAbility。则该应用在运行时,有三个进程:
......
......@@ -37,7 +37,7 @@ OpenHarmony流转提供了一组API库,可让用户应用程序更轻松、快
**图1** 流转架构图
![hop-structure](figures/hop-structure.png)
![hop-structure](figures/hop-structure.png)
- 跨端迁移任务管理:在迁移发起端,接受用户迁移的意图,提供迁移流转入口,迁移结果显示等能力。(该能力尚未构建。)
......
......@@ -14,12 +14,12 @@ Emitter的开发步骤如下:
// 定义一个eventId为1的事件
let event = {
eventId: 1
eventId: 1
};
// 收到eventId为1的事件后执行该回调
let callback = (eventData) => {
console.info('event callback');
console.info('event callback');
};
// 订阅eventId为1的事件
......@@ -30,21 +30,21 @@ Emitter的开发步骤如下:
```ts
import emitter from "@ohos.events.emitter";
// 定义一个eventId为1的事件,事件优先级为Low
let event = {
eventId: 1,
priority: emitter.EventPriority.LOW
eventId: 1,
priority: emitter.EventPriority.LOW
};
let eventData = {
data: {
"content": "c",
"id": 1,
"isEmpty": false,
}
data: {
"content": "c",
"id": 1,
"isEmpty": false,
}
};
// 发送eventId为1的事件,事件内容为eventData
emitter.emit(event, eventData);
```
......@@ -174,7 +174,7 @@ Stage卡片开发,即基于[Stage模型](stage-model-development-overview.md)
"extensionAbilities": [
{
"name": "EntryFormAbility",
"srcEnty": "./ets/entryformability/EntryFormAbility.ts",
"srcEntry": "./ets/entryformability/EntryFormAbility.ts",
"label": "$string:EntryFormAbility_label",
"description": "$string:EntryFormAbility_desc",
"type": "form",
......
......@@ -11,7 +11,7 @@
| onStartContinuation?():&nbsp;boolean; | Stage模型无对应接口 | Stage模型上,应用无需感知迁移是否成功(由应用发起迁移请求时感知),onStartContinuation废弃 |
| onSaveData?(data:&nbsp;Object):&nbsp;boolean; | \@ohos.app.ability.UIAbility.d.ts | [onContinue(wantParam&nbsp;:&nbsp;{[key:&nbsp;string]:&nbsp;any}):&nbsp;AbilityConstant.OnContinueResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) |
| onCompleteContinuation?(result:&nbsp;number):&nbsp;void; | application\ContinueCallback.d.ts | [onContinueDone(result:&nbsp;number):&nbsp;void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) |
| onRestoreData?(data:&nbsp;Object):&nbsp;void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want:&nbsp;Want,&nbsp;param:&nbsp;AbilityConstant.LaunchParam):&nbsp;void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br/>[onNewWant(want:&nbsp;Want,&nbsp;launchParams:&nbsp;AbilityConstant.LaunchParam):&nbsp;void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)<br/>多实例模式Ability迁移目标端在onCreate回调中完成数据恢复,单实例应用迁移目标端在onCreate回调中完成数据恢复,回调中通过判断launchParam.launchReason可获取迁移启动的场景,从而可以从Want中获取迁移前保存的数据 |
| onRestoreData?(data:&nbsp;Object):&nbsp;void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want:&nbsp;Want,&nbsp;param:&nbsp;AbilityConstant.LaunchParam):&nbsp;void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br/>[onNewWant(want:&nbsp;Want,&nbsp;launchParams:&nbsp;AbilityConstant.LaunchParam):&nbsp;void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)<br/>多实例模式Ability迁移目标端在onCreate回调中完成数据恢复,单实例模式应用迁移目标端在onCreate回调中完成数据恢复,回调中通过判断launchParam.launchReason可获取迁移启动的场景,从而可以从Want中获取迁移前保存的数据 |
| onRemoteTerminated?():&nbsp;void; | application\ContinueCallback.d.ts | [onContinueDone(result:&nbsp;number):&nbsp;void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) |
| onSaveAbilityState?(outState:&nbsp;PacMap):&nbsp;void; | \@ohos.app.ability.UIAbility.d.ts | [onSaveState(reason:&nbsp;AbilityConstant.StateType,&nbsp;wantParam&nbsp;:&nbsp;{[key:&nbsp;string]:&nbsp;any}):&nbsp;AbilityConstant.OnSaveResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonsavestate) |
| onRestoreAbilityState?(inState:&nbsp;PacMap):&nbsp;void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want:&nbsp;Want,&nbsp;param:&nbsp;AbilityConstant.LaunchParam):&nbsp;void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br/>应用重启后会触发Ability的onCreate方法,通过判断launchParam.launchReason可获取自恢复的场景,从而可以从Want中获取重启前保存的数据 |
......
# 任务(Mission)与启动模式
# 任务管理与启动模式
如前文所述,一个UIAbility实例对应一个任务。UIAbility实例个数与UIAbility配置的启动模式有关。在FA模型下,通过config.json配置文件中的“launchType”属性配置;在Stage模型下,通过[module.json5配置文件](../quick-start/module-configuration-file.md)中的“launchType”属性配置。
......@@ -10,12 +10,12 @@
**图1** 任务与singleton模式
![mission-and-singleton](figures/mission-and-singleton.png)
- multiton:多实例模式,每次调用startAbility()方法,都会在应用进程中创建一个该Ability的实例。
- multiton:多实例模式,每次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法,都会在应用进程中创建一个该UIAbility实例。
**图2** 任务与multiton模式
![mission-and-multiton](figures/mission-and-standard.png)
![mission-and-multiton](figures/mission-and-multiton.png)
- specified:指定实例模式,由[AbilityStage](abilitystage.md)的([onAcceptWant](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant))决定是否创建新的实例。
- specified:指定实例模式,由[AbilityStage](abilitystage.md)的([`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant))决定是否创建新的UIAbility实例。
**图3** 任务与specified模式
![mission-and-specified](figures/mission-and-specified.png)
......@@ -24,8 +24,9 @@
每个UIAbility实例都对应了一个最近任务列表中看到的Mission(任务)。
每个UIAbility实例对应的Mission都保留有该UIAbility实例的快照(Snapshot),UIAbility实例销毁后,Mission信息(包括Ability信息和任务快照)依然会保留,直到用户删除该任务。
每个UIAbility实例对应的Mission都保留有该UIAbility实例的快照(Snapshot),UIAbility实例销毁后,Mission信息(包括UIAbility信息和任务快照)依然会保留,直到用户删除该任务。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
>
> specified模式只在Stage模型上支持,FA模型不支持。
# 任务(Mission)管理场景介绍
# 任务管理场景介绍
任务(Mission)管理相关的基本概念如下:
任务管理相关的基本概念如下:
- AbilityRecord:系统服务侧管理一个UIAbility实例的最小单元,对应一个应用侧的UIAbility组件实例。系统服务侧管理UIAbility实例数量上限为512个。
......@@ -11,8 +11,8 @@
- MissionList:一个从桌面开始启动的任务列表,记录了任务之间的启动关系,上一个任务由下一个任务启动,最底部的任务由桌面启动,这里称之为任务链。
- MissionListManager:系统任务管理模块,内部维护了当前所有的任务链,与最近任务列表保持一致。
**图1** 任务管理示意图  
**图1** 任务管理示意图
![mission-list-manager](figures/mission-list-manager.png)
......@@ -28,104 +28,102 @@
- 将一个指定的任务切换到前台。
一个UIAbility实例对应一个单独的任务,因此应用调用startAbility()方法启动一个UIAbility时,就是创建了一个任务。
桌面应用调用[missionManager](../reference/apis/js-apis-application-missionManager.md)的接口管理任务,需要申请`ohos.permission.MANAGE_MISSIONS`权限,配置方式请参阅[访问控制授权申请指导](../security/accesstoken-guidelines.md#stage模型)
利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等),示例代码如下:
```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// 任务销毁
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// 任务快照变化
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// 任务被移动到前台
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// 任务图标变化
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// 任务名称变化
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// 任务实例被关闭
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);
// 2.获取系统最近20个任务
missionManager.getMissionInfos("", 20, (error, missions) => {
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
});
// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
});
// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 5.获取低分辨任务快照
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
});
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
});
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
});
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
});
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
});
// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
})
```
一个UIAbility实例对应一个单独的任务,因此应用调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动一个UIAbility时,就是创建了一个任务。
1. 桌面应用调用[missionManager](../reference/apis/js-apis-application-missionManager.md)的接口管理任务,需要申请`ohos.permission.MANAGE_MISSIONS`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等)。
```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// 任务销毁
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// 任务快照变化
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// 任务被移动到前台
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// 任务图标变化
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// 任务名称变化
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// 任务实例被关闭
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);
// 2.获取系统最近20个任务
missionManager.getMissionInfos("", 20, (error, missions) => {
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
});
// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
});
// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 5.获取低分辨任务快照
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
});
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
});
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
});
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
});
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
});
// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
})
```
# 设置任务快照的图标和名称
设置任务快照的图标和名称是为了提高用户界面的可视化性和用户体验,以便更好地管理和跟踪应用程序中的任务和功能。通过为每个任务快照设置不同的图标和名称,可以更轻松地区分和识别每个任务和功能。
默认情况下任务快照的图标和名称采用的是[module.json5配置文件](../quick-start/module-configuration-file.md)[abilities标签](../quick-start/module-configuration-file.md#abilities标签)中的icon和label字段,如下图所示。
图1 UIAbility对应的任务快照
![](figures/mission-list-recent.png)
也可以使用[UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon)[UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel)方法,根据需要自定义任务快照的图标和名称。例如,对于UIAbility的多实例启动模式,可以根据不同的功能配置相应的任务快照的图标和名称。
本文将从以下两个方面介绍。
- [设置任务快照的图标(仅对系统应用开放)](#设置任务快照的图标(仅对系统应用开放))
- [设置任务快照的名称](#设置任务快照的名称)
## 设置任务快照的图标(仅对系统应用开放)
通过调用[UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon)方法修改任务快照的图标。图片内容为[PixelMap](../reference/apis/js-apis-image.md#pixelmap7)类型对象。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let imagePixelMap: PixelMap = undefined; // 需要获取图片PixelMap信息
context.setMissionIcon(imagePixelMap, (err) => {
if (err.code) {
console.error(`Failed to set mission icon. Code is ${err.code}, message is ${err.message}`);
}
})
```
效果示意如下图所示。
图2 设置任务快照的图标
![](figures/mission-set-task-snapshot-icon.png)
## 设置任务快照的名称
通过调用[UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel)方法修改任务快照的名称。
```ts
this.context.setMissionLabel('test').then(() => {
console.info('Succeeded in seting mission label.');
}).catch((err) => {
console.error(`Failed to set mission label. Code is ${err.code}, message is ${err.message}`);
});
```
效果示意如下图所示。
图3 设置任务快照的名称
![](figures/mission-set-task-snapshot-label.png)
\ No newline at end of file
......@@ -71,5 +71,5 @@
| formsEnabled | 标识Ability是否支持卡片(forms)功能 | / | Stage模型不支持 |
| forms | 标识服务卡片的属性。该标签仅当formsEnabled为"true"时,才能生效 | form_config.json文件 | Stage模型在开发视图的resources/base/profile下面定义配置文件form_config.json |
| srcLanguage | Ability开发语言的类型 | / | Stage模型不支持 |
| srcPath | 该标签标识Ability对应的JS组件代码路径 | srcEnty | 该标签标识ability所对应的js代码路径。 |
| srcPath | 该标签标识Ability对应的JS组件代码路径 | srcEntry | 该标签标识ability所对应的js代码路径。 |
| uriPermission | 标识该Ability有权访问的应用程序数据 | / | Stage模型不支持 |
......@@ -5,7 +5,7 @@
单个UIAbility组件可以实现多个页面,并在多个页面之间跳转,这种UIAbility组件内部的页面跳转关系称为“页面栈”,由ArkUI框架统一管理,如下图中的UIAbility1的Page1-&gt;Page2-&gt;Page3和UIAbility2的PageA-&gt;PageB-&gt;PageC。
**图1** 页面栈示意图  
**图1** 页面栈示意图
![mission-record](figures/mission-record.png)
- 页面栈的形成(下面2/3/5/6步骤为页面跳转,由ArkUI管理)
......@@ -41,11 +41,11 @@
MissionList任务链记录了任务之间的拉起关系,但是这个任务链可能会断开,有以下几种情况会导致任务链的断开:
- 进入任务列表,把任务链中间某个任务移动到前台。
- 进入任务列表,把任务链中间某个任务移动到前台。
![mission-chain1](figures/mission-chain1.png)
- 进入任务列表,把任务链中间某个任务清理掉。
- 进入任务列表,把任务链中间某个任务清理掉。
![mission-chain2](figures/mission-chain2.png)
- 单实例UIAbility的任务,被不同的任务反复拉起(AbilityB为单例)。
- 单实例UIAbility的任务,被不同的任务反复拉起(AbilityB为单例)。
![mission-chain3](figures/mission-chain3.png)
......@@ -17,13 +17,13 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// singleton: 单实例模式
// standard: 多实例模式
"launchType": "standard",
// ...
...
}
]
}
......@@ -31,7 +31,7 @@
```
启动PageAbility时,对于多实例启动模式启动,以及单实例启动模式首次启动[PageAbility生命周期回调](pageability-lifecycle.md#table13118194914476)均会被触发。单实例非首次启动时不会再触发onCreate()接口,而是触发onNewWant(),onNewWant()的说明如下表2所示。
启动PageAbility时,对于多实例模式启动,以及单实例模式进行首次启动时[PageAbility生命周期回调](pageability-lifecycle.md#table13118194914476)均会被触发。单实例非首次启动时不会再触发onCreate()接口,而是触发onNewWant(),onNewWant()的说明如下表2所示。
**表2** 单实例启动模式特有的回调函数说明
......
......@@ -41,7 +41,7 @@ PageAbility生命周期回调与生命周期状态的关系如下图所示。
![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 1、PageAbility的生命周期回调均为同步接口。
>
> 2目前app.js环境中仅支持onCreate和onDestroy回调,app.ets环境支持全量生命周期回调。
> **说明:**
>
> 1. PageAbility的生命周期回调均为同步接口。
> 2. 目前app.js环境中仅支持onCreate和onDestroy回调,app.ets环境支持全量生命周期回调。
# PageAbility组件概述
PageAbility是包含UI界面、提供展示UI能力的应用组件,主要用于与用户交互。
PageAbility是包含UI、提供展示UI能力的应用组件,主要用于与用户交互。
开发者通过DevEco Studio开发平台创建PageAbility时,DevEco Studio会自动创建相关模板代码。PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过app.js/app.ets中各个回调函数实现。
......@@ -7,28 +7,26 @@
PageAbility作为可见Ability,可以通过startAbility启动有界面的且对外可见的Ability。
应用可通过在config.json中设置"abilities"中的"exported"属性设置Ability是否可由其他应用的组件启动,"exported"属性的具体参数和意义如下表所示。
应用可通过在config.json中设置"abilities"中的"visible"属性设置Ability是否可由其他应用的组件启动,"visible"属性的具体参数和意义如下表所示。
**表1** exported属性说明
**表1** visible属性说明
| 属性名称 | 描述 | 是否可缺省 |
| -------- | -------- | -------- |
| exported | 表示Ability是否可以被其他应用调用。<br/>true:该Ability可以被任何应用调用。<br/>false:该Ability只能被同一应用的其他组件调用。 | 可缺省,缺省时默认属性值为"false"。 |
| visible | 表示Ability是否可以被其他应用调用。<br/>true:该Ability可以被任何应用调用。<br/>false:该Ability只能被同一应用的其他组件调用。 | 可缺省,缺省时默认属性值为"false"。 |
如果需设置当前Ability可由任何应用访问,对应config.json文件的示例代码如下所示:
```ts
{
"module": {
// ...
...
"abilities": [
{
"exported": "true",
// ...
"visible": "true",
...
}
]
}
......@@ -36,4 +34,4 @@ PageAbility作为可见Ability,可以通过startAbility启动有界面的且
```
如果应用中的Ability包含skills过滤器,建议此属性设置为"true",以允许其他应用通过[隐式调用](explicit-implicit-want-mappings.md#隐式want匹配原理详解)启动该Ability。如果此属性设为"false",其他应用尝试启动该Ability时系统会返回PERMISSION_DENIED。这种情况下系统应用可以通过申请[START_INVISIBLE_ABILITY](../security/permission-list.md)权限启动exported为false的组件,例如系统桌面、语音助手、搜索助手等。
如果应用中的Ability包含skills过滤器,建议此属性设置为"true",以允许其他应用通过[隐式调用](explicit-implicit-want-mappings.md)启动该Ability。如果此属性设为"false",其他应用尝试启动该Ability时系统会返回PERMISSION_DENIED。这种情况下系统应用可以通过申请[START_INVISIBLE_ABILITY](../security/permission-list.md)权限启动visible为false的组件,例如系统桌面、语音助手、搜索助手等。
......@@ -9,37 +9,7 @@
在config.json声明需要的权限,在module下添加"reqPermissions",并写入对应权限。
例如申请访问日历权限:
如申请访问日历权限,需要申请`ohos.permission.READ_CALENDAR`权限,配置方式请参阅[访问控制授权申请指导](../security/accesstoken-guidelines.md#stage模型)
对应config.json文件的示例代码如下所示:
```json
{
"module": {
// ...
"reqPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
// ...
}
]
}
}
```
通过动态弹窗向用户申请授权:
```ts
import featureAbility from '@ohos.ability.featureAbility';
let context = featureAbility.getContext();
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions, 1).then((data) => {
console.info("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)
2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)
......@@ -6,8 +6,7 @@
## 服务卡片架构
**图1** 服务卡片架构
**图1** 服务卡片架构
![WidgetArchitecture](figures/WidgetArchitecture.png)
卡片的基本概念:
......@@ -24,7 +23,7 @@
卡片的常见使用步骤如下。
**图2** 卡片常见使用步骤
**图2** 卡片常见使用步骤
![WidgetUse](figures/WidgetUse.png)
......@@ -55,4 +54,4 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上
| 自定义绘制 | 不支持 | 支持 |
| 逻辑代码执行(不包含import能力) | 不支持 | 支持 |
相比于JS卡片,ArkTS卡片在能力和场景方面更加丰富,因此无论开发何种用途的卡片,都推荐使用ArkTS卡片,因为它可以提高开发效率并实现动态化。但如果只需要做静态页面展示的卡片,可以考虑使用JS卡片。
推荐在开发需求需要动态能力的卡片时使用ArkTS卡片,因为它拥有更加丰富的能力和适应更多的场景,能够提高效率并实现动态化。但如果只需要静态展示卡片,可以考虑使用JS卡片。
......@@ -5,23 +5,23 @@
下图展示了Stage模型中的基本概念。
**图1** Stage模型概念图  
**图1** Stage模型概念图
![stage-concepts](figures/stage-concepts.png)
- [UIAbility组件](uiability-overview.md)[ExtensionAbility组件](extensionability-overview.md)
Stage模型提供UIAbility和ExtensionAbility两种类型的组件,这两种组件都有具体的类承载,支持面向对象的开发方式。
- UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。例如,图库类应用可以在UIAbility组件中展示图片瀑布流,在用户选择某个图片后,在新的页面中展示图片的详细内容。同时用户可以通过返回键返回到瀑布流页面。UIAbility的生命周期只包含创建/销毁/前台/后台等状态,与显示相关的状态通过WindowStage的事件暴露给开发者。
- UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。例如,图库类应用可以在UIAbility组件中展示图片瀑布流,在用户选择某个图片后,在新的页面中展示图片的详细内容。同时用户可以通过返回键返回到瀑布流页面。UIAbility的生命周期只包含创建/销毁/前台/后台等状态,与显示相关的状态通过WindowStage的事件暴露给开发者。
- ExtensionAbility组件是一种面向特定场景的应用组件。开发者并不直接从ExtensionAbility派生,而是需要使用ExtensionAbility的派生类。目前ExtensionAbility有用于卡片场景的FormExtensionAbility,用于输入法场景的InputMethodExtensionAbility,用于闲时任务场景的WorkSchedulerExtensionAbility等多种派生类,这些派生类都是基于特定场景提供的。例如,用户在桌面创建应用的卡片,需要应用开发者从FormExtensionAbility派生,实现其中的回调函数,并在配置文件中配置该能力。ExtensionAbility派生类实例由用户触发创建,并由系统管理生命周期。在Stage模型上,普通应用开发者不能开发自定义服务,而需要根据自身的业务场景通过ExtensionAbility的派生类来实现。
- [WindowStage](../windowmanager/application-window-stage.md)
每个UIAbility类实例都会与一个WindowStage类实例绑定,该类提供了应用进程内窗口管理器的作用。它包含一个主窗口。也就是说UIAbility通过WindowStage持有了一个窗口,该窗口为ArkUI提供了绘制区域。
每个UIAbility类实例都会与一个WindowStage类实例绑定,该类提供了应用进程内窗口管理器的作用。它包含一个主窗口(Window)。也就是说UIAbility通过WindowStage持有了一个主窗口,该主窗口为ArkUI提供了绘制区域。
- [Context](application-context-stage.md)
在Stage模型上,Context及其派生类向开发者提供在运行期可以调用的各种能力。UIAbility组件和各种ExtensionAbility派生类都有各自不同的Context类,他们都继承自基类Context,但是各自又根据所属组件,提供不同的能力。
在Stage模型上,Context及其派生类向开发者提供在运行期可以调用的各种资源和能力。UIAbility组件和各种ExtensionAbility派生类都有各自不同的Context类,他们都继承自基类Context,但是各自又根据所属组件,提供不同的能力。
- [AbilityStage](abilitystage.md)
......@@ -32,7 +32,7 @@
基于Stage模型开发应用时,在应用模型部分,涉及如下开发过程。
**表1** Stage模型开发流程
**表1** Stage模型开发流程
| 任务 | 简介 | 相关指导 |
| -------- | -------- | -------- |
......@@ -40,4 +40,4 @@
| 进程间通信 | 本章节介绍了Stage模型的进程模型以及几种常用的进程间通信方式。 | -&nbsp;[公共事件](common-event-overview.md)<br/>-&nbsp;[后台服务](background-services.md) |
| 线程间通信 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | -&nbsp;[Emitter](itc-with-emitter.md)<br/>-&nbsp;[Worker](itc-with-worker.md) |
| 任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | -&nbsp;[任务管理场景介绍](mission-management-overview.md)<br/>-&nbsp;[任务管理与启动模式](mission-management-launch-type.md)<br/>-&nbsp;[页面栈和任务链](page-mission-stack.md) |
| 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | [Stage模型应用配置文件](../quick-start/application-configuration-file-overview-stage.md) |
| 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | [Stage模型应用配置文件](config-file-stage.md) |
......@@ -23,7 +23,7 @@ import featureAbility from '@ohos.ability.featureAbility'
want: {
bundleName: "com.example.myapplication",
moduleName: "entry",
abilityName: "com.example.myapplication.MainAbility"
abilityName: "com.example.myapplication.EntryAbility"
}
}
await featureAbility.startAbility(param)
......
......@@ -12,7 +12,7 @@ import featureAbility from '@ohos.ability.featureAbility';
async function restartAbility() {
let wantInfo = {
bundleName: "com.sample.MyApplication",
abilityName: "MainAbility",
abilityName: "EntryAbility",
parameters: {
page: "pages/second"
}
......@@ -70,7 +70,7 @@ struct Index {
```
当PageAbility的启动模式设置为多实例模式,或为首次启动的单实例模式的PageAbility时(具体设置方法和典型场景示例见[PageAbility的启动模式](pageability-launch-type.md)),在调用方PageAbility中,通过want中的parameters参数传递要启动的指定页面的pages信息,调用startAbility()方法启动PageAbility。被调用方可以在onCreate中使用featureAbility的getWant方法获取want,再通过调用router.push实现启动指定页面。
当PageAbility的启动模式设置为多实例模式或为首次启动单例模式的PageAbility时(具体设置方法和典型场景示例见[PageAbility的启动模式](pageability-launch-type.md)),在调用方PageAbility中,通过want中的parameters参数传递要启动的指定页面的pages信息,调用startAbility()方法启动PageAbility。被调用方可以在onCreate中使用featureAbility的getWant方法获取want,再通过调用router.push实现启动指定页面。
调用方的页面中实现按钮点击触发startAbility方法启动目标端PageAbility,startAbility方法的入参want中携带指定页面信息,示例代码如下:
......@@ -83,13 +83,13 @@ struct Index {
@State message: string = 'Hello World'
build() {
// ...
...
Button("startAbility")
.onClick(() => {
featureAbility.startAbility({
want: {
bundleName: "com.exm.myapplication",
abilityName: "com.exm.myapplication.MainAbility",
abilityName: "com.exm.myapplication.EntryAbility",
parameters: { page: "pages/page1" }
}
}).then((data) => {
......@@ -98,13 +98,13 @@ struct Index {
console.info("startAbility failed errcode:" + err.code)
})
})
// ...
...
Button("page2")
.onClick(() => {
featureAbility.startAbility({
want: {
bundleName: "com.exm.myapplication",
abilityName: "com.exm.myapplication.MainAbility",
abilityName: "com.exm.myapplication.EntryAbility",
parameters: { page: "pages/page2" }
}
}).then((data) => {
......@@ -113,7 +113,7 @@ struct Index {
console.info("startAbility failed errcode:" + err.code)
})
})
// ...
...
}
}
```
......@@ -136,7 +136,7 @@ export default {
})
},
onDestroy() {
// ...
...
},
}
```
......@@ -9,23 +9,23 @@
UIAbility启动PageAbility和UIAbility启动UIAbility的方式完全相同。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends UIAbility {
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
console.info("MainAbility onCreate")
console.info("EntryAbility onCreate")
}
onDestroy() {
console.info("MainAbility onDestroy")
console.info("EntryAbility onDestroy")
}
onWindowStageCreate(windowStage) {
console.info("MainAbility onWindowStageCreate")
console.info("EntryAbility onWindowStageCreate")
windowStage.loadContent('pages/Index', (err, data) => {
// ...
...
});
let want = {
bundleName: "com.ohos.fa",
abilityName: "MainAbility",
abilityName: "EntryAbility",
};
this.context.startAbility(want).then(() => {
console.info('Start Ability successfully.');
......@@ -34,13 +34,13 @@ export default class MainAbility extends UIAbility {
});
}
onWindowStageDestroy() {
console.info("MainAbility onWindowStageDestroy")
console.info("EntryAbility onWindowStageDestroy")
}
onForeground() {
console.info("MainAbility onForeground")
console.info("EntryAbility onForeground")
}
onBackground() {
console.info("MainAbility onBackground")
console.info("EntryAbility onBackground")
}
}
```
......@@ -54,23 +54,23 @@ UIAbility通过startAbilityForResult启动PageABility和UIAbility通过startAbil
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends UIAbility {
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
console.info("MainAbility onCreate")
console.info("EntryAbility onCreate")
}
onDestroy() {
console.info("MainAbility onDestroy")
console.info("EntryAbility onDestroy")
}
onWindowStageCreate(windowStage) {
console.info("MainAbility onWindowStageCreate")
console.info("EntryAbility onWindowStageCreate")
windowStage.loadContent('pages/Index', (err, data) => {
// ...
...
});
let want = {
bundleName: "com.ohos.fa",
abilityName: "MainAbility",
abilityName: "EntryAbility",
};
this.context.startAbilityForResult(want).then((result) => {
console.info('Ability verify result: ' + JSON.stringify(result));
......@@ -79,13 +79,13 @@ export default class MainAbility extends UIAbility {
});
}
onWindowStageDestroy() {
console.info("MainAbility onWindowStageDestroy")
console.info("EntryAbility onWindowStageDestroy")
}
onForeground() {
console.info("MainAbility onForeground")
console.info("EntryAbility onForeground")
}
onBackground() {
console.info("MainAbility onBackground")
console.info("EntryAbility onBackground")
}
}
```
......@@ -110,7 +110,7 @@ export default class ServiceExtension extends Extension {
console.info("ServiceExtension onRequest")
let wantFA = {
bundleName: "com.ohos.fa",
abilityName: "MainAbility",
abilityName: "EntryAbility",
};
this.context.startAbility(wantFA).then(() => {
console.info('Start Ability successfully.');
......
......@@ -87,28 +87,31 @@ async function RequestPermission() {
如下示例展示了通过getTrustedDeviceListSync获取可信设备列表,选择设备的方法。
```ts
import deviceManager from '@ohos.distributedHardware.deviceManager';
let dmClass;
import deviceManager from '@ohos.distributedHardware.deviceManager';
let dmClass;
function getDeviceManager() {
deviceManager.createDeviceManager('ohos.example.distributedService', (error, dm) => {
if (error) {
console.info('create device manager failed with ' + error)
}
dmClass = dm;
})
deviceManager.createDeviceManager('ohos.example.distributedService', (error, dm) => {
if (error) {
console.info('create device manager failed with ' + error)
}
dmClass = dm;
})
}
function getRemoteDeviceId() {
if (typeof dmClass === 'object' && dmClass != null) {
let list = dmClass.getTrustedDeviceListSync();
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
console.info("MainAbility onButtonClick getRemoteDeviceId err: list is null");
return;
}
console.info("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
return list[0].deviceId;
} else {
console.info("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
}
function getRemoteDeviceId() {
if (typeof dmClass === 'object' && dmClass != null) {
let list = dmClass.getTrustedDeviceListSync();
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
console.info("EntryAbility onButtonClick getRemoteDeviceId err: list is null");
return;
}
console.info("EntryAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
return list[0].deviceId;
} else {
console.info("EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null");
}
}
```
......@@ -120,21 +123,22 @@ function getRemoteDeviceId() {
```ts
import featureAbility from '@ohos.ability.featureAbility';
function onStartRemoteAbility() {
console.info('onStartRemoteAbility begin');
let params;
let wantValue = {
bundleName: 'ohos.samples.etsDemo',
abilityName: 'ohos.samples.etsDemo.RemoteAbility',
deviceId: getRemoteDeviceId(), // getRemoteDeviceId的定义在前面的示例代码中
parameters: params
};
console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
featureAbility.startAbility({
want: wantValue
}).then((data) => {
console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
});
console.info('onStartRemoteAbility end');
function onStartRemoteAbility() {
console.info('onStartRemoteAbility begin');
let params;
let wantValue = {
bundleName: 'ohos.samples.etsDemo',
abilityName: 'ohos.samples.etsDemo.RemoteAbility',
deviceId: getRemoteDeviceId(), // getRemoteDeviceId的定义在前面的示例代码中
parameters: params
};
console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue));
featureAbility.startAbility({
want: wantValue
}).then((data) => {
console.info('onStartRemoteAbility finished, ' + JSON.stringify(data));
});
console.info('onStartRemoteAbility end');
}
```
......@@ -27,7 +27,7 @@ async function startServiceAbility() {
```
执行上述代码后,Ability将通过startAbility() 方法来启动ServiceAbility。
执行上述代码后,Ability将通过[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法来启动ServiceAbility。
- 如果ServiceAbility尚未运行,则系统会先调用onStart()来初始化ServiceAbility,再回调Service的onCommand()方法来启动ServiceAbility。
......
......@@ -14,7 +14,7 @@ import featureAbility from '@ohos.ability.featureAbility';
let parameter = {
"want": {
bundleName: "com.ohos.stage",
abilityName: "com.ohos.stage.MainAbility"
abilityName: "com.ohos.stage.EntryAbility"
}
};
featureAbility.startAbility(parameter).then((code) => {
......@@ -38,7 +38,7 @@ import featureAbility from '@ohos.ability.featureAbility';
let parameter = {
"want": {
bundleName: "com.ohos.stage",
abilityName: "com.ohos.stage.MainAbility"
abilityName: "com.ohos.stage.EntryAbility"
}
};
featureAbility.startAbilityForResult(parameter).then((result) => {
......@@ -60,7 +60,7 @@ import particleAbility from '@ohos.ability.particleAbility';
let parameter = {
"want": {
bundleName: "com.ohos.stage",
abilityName: "com.ohos.stage.MainAbility"
abilityName: "com.ohos.stage.EntryAbility"
}
};
particleAbility.startAbility(parameter).then(() => {
......
# 订阅系统环境变量的变化
系统环境变量是指:在应用程序运行期间,终端设备的系统设置(例如系统的语言环境、屏幕方向等)发生变化。
开发者通过订阅系统环境变化,可以使应用程序及时感知这种变化,并作出相应处理,从而提供更好的用户体验。例如,用户更改系统语言设置时,应用程序可以自动根据新的语言设置更新用户界面的语言;当用户将设备旋转到横屏或者竖屏时,应用程序可以重新布局用户界面,以适应屏幕方向和尺寸。
系统配置的变化通常由“设置”中的选项或“控制中心”中的图标触发。订阅系统环境变量变化,可以使应用程序更加智能地响应系统环境变化,从而提供更好的用户体验。查看当前支持订阅变化的系统环境变量,请参见[Configuration](../reference/apis/js-apis-app-ability-configuration.md)
基于OpenHarmony应用模型,可以通过以下几种方式来实现订阅系统环境变量的变化。
- [使用ApplicationContext订阅回调](#使用applicationcontext订阅回调)
- [在AbilityStage组件容器中订阅回调](#在abilitystage组件容器中订阅回调)
- [在UIAbility组件中订阅回调](#在uiability组件中订阅回调)
- [在ExtensionAbility组件中订阅回调](#在extensionability组件中订阅回调)
## 使用ApplicationContext订阅回调
[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md)提供了注册回调函数以订阅系统环境变量的变化,并且可以通过调用相应的方法来撤销该回调。这有助于在资源不再需要时释放相关资源,从而提高系统的可靠性和性能。
1. 使用`ApplicationContext.on(type: 'environment', callback: EnvironmentCallback)`方法,应用程序可以通过在非应用组件模块中订阅系统环境变量的变化来动态响应这些变化。例如,使用该方法在页面中监测系统语言的变化。
```ts
import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
private callbackId: number; // 注册订阅系统环境变化的ID
subscribeConfigurationUpdate() {
let systemLanguage: string = this.context.config.language; // 获取系统当前语言
// 1.获取ApplicationContext
let applicationContext = this.context.getApplicationContext();
// 2.通过applicationContext订阅环境变量变化
let environmentCallback = {
onConfigurationUpdated(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
if (this.systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
},
onMemoryLevel(level) {
console.info(`onMemoryLevel level: ${level}`);
}
}
this.callbackId = applicationContext.on('environment', environmentCallback);
}
// 页面展示
build() {
...
}
}
```
2. 在资源使用完成之后,可以通过调用`ApplicationContext.off(type: 'environment', callbackId: number)`方法释放相关资源。
```ts
import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
private callbackId: number; // 注册订阅系统环境变化的ID
unsubscribeConfigurationUpdate() {
let applicationContext = this.context.getApplicationContext();
applicationContext.off('environment', this.callbackId);
}
// 页面展示
build() {
...
}
}
```
## 在AbilityStage组件容器中订阅回调
使用[AbilityStage.onConfigurationUpdate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate)回调方法订阅系统环境变量的变化。当系统环境变量发生变化时,会调用该回调方法。在该方法中,通过[Configuration](../reference/apis/js-apis-app-ability-configuration.md)对象获取最新的系统环境配置信息。可以进行相应的界面适配等操作,从而提高系统的灵活性和可维护性。
> **说明:**
>
> - DevEco Studio默认工程中未自动生成AbilityStage,AbilityStage文件的创建请参见[AbilityStage组件容器](abilitystage.md)。
> - 当使用回调方法订阅系统环境变量的变化时,该回调方法会随着[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md)的生命周期而存在,在Module销毁时一并销毁。
例如,在[AbilityStage.onConfigurationUpdate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate)回调方法中实现监测系统语言的变化。
```ts
import AbilityStage from '@ohos.app.ability.AbilityStage';
let systemLanguage: string; // 系统当前语言
export default class MyAbilityStage extends AbilityStage {
onCreate() {
systemLanguage = this.context.config.language; // Module首次加载时,获取系统当前语言
console.info(`systemLanguage is ${systemLanguage} `);
}
onConfigurationUpdate(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
if (systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
}
}
```
## 在UIAbility组件中订阅回调
UIAbility组件提供了`UIAbility.onConfigurationUpdate()`回调方法用于订阅系统环境变量的变化。当系统环境变量发生变化时,会调用该回调方法。在该方法中,通过[Configuration](../reference/apis/js-apis-app-ability-configuration.md)对象获取最新的系统环境配置信息,而无需重启UIAbility。
> **说明:**
>
> 当使用回调方法订阅系统环境变量的变化时,该回调方法会随着UIAbility的生命周期而存在,在UIAbility销毁时一并销毁。
例如,在`onConfigurationUpdate()`回调方法中实现监测系统语言的变化。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
let systemLanguage: string; // 系统当前语言
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
systemLanguage = this.context.config.language; // UIAbility实例首次加载时,获取系统当前语言
console.info(`systemLanguage is ${systemLanguage} `);
}
onConfigurationUpdate(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
if (systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
}
...
}
```
## 在ExtensionAbility组件中订阅回调
ExtensionAbility组件提供了`onConfigurationUpdate()`回调方法用于订阅系统环境变量的变化。当系统环境变量发生变化时,会调用该回调方法。在该方法中,通过[Configuration](../reference/apis/js-apis-app-ability-configuration.md)对象获取最新的系统环境配置信息。
> **说明:**
>
> 当使用回调方法订阅系统环境变量的变化时,该回调方法会随着ExtensionAbility的生命周期而存在,在ExtensionAbility销毁时一并销毁。
以FormExtensionAbility为例说明。例如,在`onConfigurationUpdate()`回调方法中实现系统环境变量的变化。
```ts
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
export default class EntryFormAbility extends FormExtensionAbility {
onConfigurationUpdate(newConfig) {
console.info(`newConfig is ${JSON.stringify(newConfig)}`);
}
...
}
```
......@@ -21,5 +21,5 @@ FA模型下的线程主要有如下三类:
基于OpenHarmony的线程模型,不同的业务功能运行在不同的线程上,业务功能的交互就需要线程间通信。线程间通信目前主要有Emitter和Worker两种方式,其中Emitter主要适用于线程间的事件同步, Worker主要用于新开一个线程执行耗时任务。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> FA模型每个ability都有一个独立的线程,Emiter可用于Ability线程内、Ability线程间、Ability线程与Worker线程的事件同步。
# UIAbility组件与UI的数据同步
基于OpenHarmony的应用模型,可以通过以下种方式来实现UIAbility组件与UI之间的数据同步。
基于OpenHarmony的应用模型,可以通过以下种方式来实现UIAbility组件与UI之间的数据同步。
1. EventHub:基于发布订阅模式来实现,事件需要先订阅后发布,订阅者收到消息后进行处理。
2. globalThis:ArkTS引擎实例内部的一个全局对象,在ArkTS引擎实例内部都能访问。
- [使用EventHub进行数据通信](#使用eventhub进行数据通信):在基类Context中提供了EventHub对象,可以通过发布订阅方式来实现事件的传递。在事件传递前,订阅者需要先进行订阅,当发布者发布事件时,订阅者将接收到事件并进行相应处理。
- [使用globalThis进行数据同步](#使用globalthis进行数据同步):在ArkTS引擎实例内部,globalThis是一个全局对象,可以被UIAbility、ExtensionAbility、Page等组件访问。
- [使用AppStorage/LocalStorage进行数据同步](#使用appstorage/localstorage进行数据同步):ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。
## 使用EventHub进行数据通信
EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,以UIAbility组件/ExtensionAbility组件为中心提供了订阅、取消订阅和触发事件的数据通信能力。接口说明请参见[EventHub](../reference/apis/js-apis-inner-application-eventHub.md)
[EventHub](../reference/apis/js-apis-inner-application-eventHub.md)为UIAbility组件/ExtensionAbility组件提供了事件机制,使它们能够进行订阅、取消订阅和触发事件等数据通信能力
使用EventHub之前,首先需要获取EventHub对象。[基类Context](application-context-stage.md)提供了EventHub对象,本章节以使用EventHub实现UIAbility与UI之间的数据通信为例进行说明。
[基类Context](application-context-stage.md)中,提供了EventHub对象,使用EventHub实现UIAbility与UI之间的数据通信需要先获取EventHub对象。本章节将以此为例进行说明。
1. 在UIAbility中调用eventHub.on()方法注册一个自定义事件“event1”,eventHub.on()有如下两种调用方式,使用其中一种即可。
1. 在UIAbility中调用[`eventHub.on()`](../reference/apis/js-apis-inner-application-eventHub.md#eventhubon)方法注册一个自定义事件“event1”,[`eventHub.on()`](../reference/apis/js-apis-inner-application-eventHub.md#eventhubon)有如下两种调用方式,使用其中一种即可。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
......@@ -23,25 +22,25 @@ EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,
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));
});
}
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));
});
}
}
```
2. 在UI界面中通过eventHub.emit()方法触发该事件,在触发事件的同时,根据需要传入参数信息。
2. 在UI中通过[eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit)方法触发该事件,在触发事件的同时,根据需要传入参数信息。
```ts
import common from '@ohos.app.ability.common';
......@@ -63,7 +62,7 @@ EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,
// 页面展示
build() {
// ...
...
}
}
```
......@@ -78,7 +77,7 @@ EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,
[2,'test']
```
4. 在自定义事件“event1”使用完成后,可以根据需要调用eventHub.off()方法取消该事件的订阅。
4. 在自定义事件“event1”使用完成后,可以根据需要调用[eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff)方法取消该事件的订阅。
```ts
// context为UIAbility实例的AbilityContext
......@@ -88,12 +87,10 @@ EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,
## 使用globalThis进行数据同步
globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对象,引擎内部的UIAbility/ExtensionAbility/Page都可以使用,因此可以使用globalThis对象进行数据同步。
globalThis是ArkTS引擎实例内部的一个全局对象,引擎内部的UIAbility/ExtensionAbility/Page都可以使用,因此可以使用globalThis全局对象进行数据同步。
**图1** 使用globalThis进行数据同步
![globalThis1](figures/globalThis1.png)
**图1** 使用globalThis进行数据同步
![globalThis1](figures/globalThis1.png)
如上图所示,下面从如下三个场景和一个注意点来介绍globalThis的使用:
......@@ -105,24 +102,24 @@ globalThis是ArkTS引擎实例内部的一个全局对象,引擎内部的UIAbi
### UIAbility和Page之间使用globalThis
globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可以通过globalThis绑定属性/方法来进行UIAbility组件与UI的数据同步。例如在UIAbility组件中绑定want参数,即可在UIAbility对应的UI界面上使用want参数信息。
通过在globalThis对象上绑定属性/方法,可以实现UIAbility组件与UI之间的数据同步。例如在UIAbility组件中绑定want参数,即可在UIAbility对应的UI上使用want参数信息。
1. 调用startAbility()方法启动一个UIAbility实例时,被启动的UIAbility创建完成后会进入onCreate()生命周期回调,且在onCreate()生命周期回调中能够接受到传递过来的want参数,可以将want参数绑定到globalThis上。
1. 调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动一个UIAbility实例时,被启动的UIAbility创建完成后会进入[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)生命周期回调,且在[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)生命周期回调中能够接受到传递过来的want参数,可以将want参数绑定到globalThis上。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launch) {
globalThis.entryAbilityWant = want;
// ...
}
onCreate(want, launch) {
globalThis.entryAbilityWant = want;
...
}
// ...
...
}
```
2. 在UI界面中即可通过globalThis获取到want参数信息。
2. 在UI中即可通过globalThis获取到want参数信息。
```ts
let entryAbilityWant;
......@@ -136,7 +133,7 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
// 页面展示
build() {
// ...
...
}
}
```
......@@ -144,51 +141,51 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
### UIAbility和UIAbility之间使用globalThis
同一个应用中UIAbility和UIAbility之间的数据传递,可以通过将数据绑定到全局变量globalThis上进行同步,如在AbilityA中将数据保存在globalThis,然后跳转到AbilityB中取得该数据:
在同一个应用中,UIAbility与UIAbility之间的数据传递可以通过将数据绑定到全局变量globalThis上进行同步。例如,在UIAbilityA中将数据保存在globalThis对象中,然后跳转到UIAbilityB中就可以获取该数据。
1. AbilityA中保存数据一个字符串数据并挂载到globalThis上。
1. UIAbilityA中保存数据一个字符串数据并挂载到globalThis上。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.entryAbilityStr = 'AbilityA'; // AbilityA存放字符串“AbilityA”到globalThis
// ...
}
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.entryAbilityStr = 'UIAbilityA'; // UIAbilityA存放字符串“UIAbilityA”到globalThis
...
}
}
```
2. AbilityB中获取对应的数据。
2. UIAbilityB中获取对应的数据。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityB extends UIAbility {
onCreate(want, launch) {
// AbilityB从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
// ...
}
export default class UIAbilityB extends UIAbility {
onCreate(want, launch) {
// UIAbilityB从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
...
}
}
```
### UIAbility和ExtensionAbility之间使用globalThis
同一个应用中UIAbility和ExtensionAbility之间的数据传递,也可以通过将数据绑定到全局变量globalThis上进行同步,如在AbilityA中保存数据,在ServiceExtensionAbility中获取数据。
在同一个应用中,UIAbility和ExtensionAbility之间的数据传递也可以通过将数据绑定到全局变量globalThis上进行同步。例如,在UIAbilityA中保存数据,在ServiceExtensionAbility中就可以获取该数据。
1. AbilityA中保存数据一个字符串数据并挂载到globalThis上。
1. UIAbilityA中保存数据一个字符串数据并挂载到globalThis上。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityA extends UIAbility {
onCreate(want, launch) {
// AbilityA存放字符串“AbilityA”到globalThis
globalThis.entryAbilityStr = 'AbilityA';
// ...
}
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
// UIAbilityA存放字符串“UIAbilityA”到globalThis
globalThis.entryAbilityStr = 'UIAbilityA';
...
}
}
```
......@@ -198,22 +195,21 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
import Extension from '@ohos.app.ability.ServiceExtensionAbility'
export default class ServiceExtAbility extends Extension {
onCreate(want) {
// ServiceExtAbility从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
// ...
}
onCreate(want) {
// ServiceExtAbility从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
...
}
}
```
### globalThis使用的注意事项
**图2** globalThis注意事项
**图2** globalThis注意事项
![globalThis2](figures/globalThis2.png)
- Stage模型下进程内的UIAbility组件共享ArkTS引擎实例,使用globalThis时需要避免存放相同名称的对象。例如AbilityA和AbilityB可以使用globalThis共享数据,在存放相同名称的对象时,先存放的对象会被后存放的对象覆盖。
- Stage模型下进程内的UIAbility组件共享ArkTS引擎实例,使用globalThis时需要避免存放相同名称的对象。例如UIAbilityA和UIAbilityB可以使用globalThis共享数据,在存放相同名称的对象时,先存放的对象会被后存放的对象覆盖。
- FA模型因为每个UIAbility组件之间引擎隔离,不会存在该问题。
......@@ -221,20 +217,20 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
Stage模型上同名对象覆盖导致问题的场景举例说明。
1. 在AbilityA文件中使用globalThis中存放了[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)
1.UIAbilityA文件中使用globalThis中存放了[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.context = this.context; // AbilityA存放context到globalThis
// ...
}
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.context = this.context; // UIAbilityA存放context到globalThis
...
}
}
```
2.AbilityA的页面中获取该[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)并进行使用。使用完成后将AbilityA实例切换至后台。
2.UIAbilityA的页面中获取该[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)并进行使用。使用完成后将UIAbilityA实例切换至后台。
```ts
@Entry
......@@ -242,33 +238,29 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
struct Index {
onPageShow() {
let ctx = globalThis.context; // 页面中从globalThis中取出context并使用
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
// ...
});
}
// 页面展示
build() {
// ...
...
}
}
```
3. 在AbilityB文件中使用globalThis中存放了[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),并且命名为相同的名称。
3.UIAbilityB文件中使用globalThis中存放了[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),并且命名为相同的名称。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityB extends UIAbility {
onCreate(want, launch) {
// AbilityB覆盖了AbilityA在globalThis中存放的context
globalThis.context = this.context;
// ...
}
export default class UIAbilityB extends UIAbility {
onCreate(want, launch) {
// UIAbilityB覆盖了UIAbilityA在globalThis中存放的context
globalThis.context = this.context;
...
}
}
```
4.AbilityB的页面中获取该[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)并进行使用。此时获取到的globalThis.context已经表示为AbilityB中赋值的[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)内容。
4.UIAbilityB的页面中获取该[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)并进行使用。此时获取到的globalThis.context已经表示为UIAbilityB中赋值的[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)内容。
```ts
@Entry
......@@ -276,47 +268,43 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
struct Index {
onPageShow() {
let ctx = globalThis.context; // Page中从globalThis中取出context并使用
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
}
// 页面展示
build() {
// ...
...
}
}
```
5.AbilityB实例切换至后台,将AbilityA实例从后台切换回到前台。此时AbilityA的onCreate生命周期不会再次进入。
5.UIAbilityB实例切换至后台,将UIAbilityA实例从后台切换回到前台。此时UIAbilityA的onCreate生命周期不会再次进入。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityA extends UIAbility {
onCreate(want, launch) { // AbilityA从后台进入前台,不会再走这个生命周期
globalThis.context = this.context;
// ...
}
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) { // UIAbilityA从后台进入前台,不会再走这个生命周期
globalThis.context = this.context;
...
}
}
```
6.AbilityA的页面再次回到前台时,其获取到的globalThis.context表示的为AbilityB的[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),而不是AbilityA的[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),在AbilityA的页面中使用则会出错。
6.UIAbilityA的页面再次回到前台时,其获取到的globalThis.context表示的为UIAbilityB的[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),而不是UIAbilityA的[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md),在UIAbilityA的页面中使用则会出错。
```ts
@Entry
@Component
struct Index {
onPageShow() {
let ctx = globalThis.context; // 这时候globalThis中的context是AbilityB的context
let permissions=['com.example.permission'];
ctx.requestPermissionsFromUser(permissions,(result) => { // 使用这个对象就会导致进程崩溃
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
let ctx = globalThis.context; // 这时候globalThis中的context是UIAbilityB的context
}
// 页面展示
build() {
// ...
...
}
}
```
## 使用AppStorage/LocalStorage进行数据同步
ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。使用这些方案可以方便地管理应用状态,提高应用性能和用户体验。其中,AppStorage是一个全局的状态管理器,适用于多个UIAbility共享同一状态数据的情况;而LocalStorage则是一个局部的状态管理器,适用于单个UIAbility内部使用的状态数据。通过这两种方案,开发者可以更加灵活地控制应用状态,提高应用的可维护性和可扩展性。详细请参见[应用级变量的状态管理](../quick-start/arkts-application-state-management-overview.md)
......@@ -15,12 +15,12 @@ UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态
singleton启动模式为单实例模式,也是默认情况下的启动模式。
每次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
每次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
**图1** 单实例模式演示效果
![uiability-launch-type1](figures/uiability-launch-type1.gif)
> **说明**:应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例。由于启动的还是原来的UIAbility实例,并未重新创建一个新的UIAbility实例,此时只会进入该UIAbility的[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调,不会进入其[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
> **说明**:应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例。由于启动的还是原来的UIAbility实例,并未重新创建一个新的UIAbility实例,此时只会进入该UIAbility的[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调,不会进入其[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[`onWindowStageCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
如果需要使用singleton启动模式,在[module.json5配置文件](../quick-start/module-configuration-file.md)中的`launchType`字段配置为`singleton`即可。
......@@ -28,11 +28,11 @@ singleton启动模式为单实例模式,也是默认情况下的启动模式
```json
{
"module": {
// ...
...
"abilities": [
{
"launchType": "singleton",
// ...
...
}
]
}
......@@ -42,7 +42,7 @@ singleton启动模式为单实例模式,也是默认情况下的启动模式
## multiton启动模式
multiton启动模式为多实例模式,每次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
multiton启动模式为多实例模式,每次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
**图2** 多实例模式演示效果
![uiability-launch-type2](figures/uiability-launch-type2.gif)
......@@ -53,11 +53,11 @@ multiton启动模式的开发使用,在[module.json5配置文件](../quick-sta
```json
{
"module": {
// ...
...
"abilities": [
{
"launchType": "multiton",
// ...
...
}
]
}
......@@ -79,67 +79,68 @@ specified启动模式为指定实例模式,针对一些特殊场景使用(
```json
{
"module": {
// ...
...
"abilities": [
{
"launchType": "specified",
// ...
...
}
]
}
}
```
2. 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用[startAbility()](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用[startAbility()](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,可以在`want`参数中增加一个自定义参数,例如`instanceKey`,以此来区分不同的UIAbility实例。
2. 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用[`startAbility()`](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用[`startAbility()`](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,可以在`want`参数中增加一个自定义参数,例如`instanceKey`,以此来区分不同的UIAbility实例。
```ts
// 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
// 例如在文档使用场景中,可以用文档路径作为Key标识
function getInstance() {
// ...
...
}
let context = ...; // context为调用方UIAbility的UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'SpecifiedAbility',
moduleName: 'module1', // moduleName非必选
parameters: { // 自定义信息
instanceKey: getInstance(),
},
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'SpecifiedAbility',
moduleName: 'specified', // moduleName非必选
parameters: { // 自定义信息
instanceKey: getInstance(),
},
}
// context为调用方UIAbility的UIAbilityContext
this.context.startAbility(want).then(() => {
// ...
context.startAbility(want).then(() => {
console.info('Succeeded in starting ability.');
}).catch((err) => {
// ...
console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`);
})
```
3. 由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的[onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)回调函数和[onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)回调函数。
3. 由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)回调函数和[`onWindowStageCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)回调函数。
示例代码中,通过实现[onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调函数,解析传入的`want`参数,获取自定义参数`instanceKey`。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。
示例代码中,通过实现[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调函数,解析传入的`want`参数,获取自定义参数`instanceKey`。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。
```ts
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage {
onAcceptWant(want): string {
// 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
// 当前示例指的是module1 Module的SpecifiedAbility
if (want.abilityName === 'SpecifiedAbility') {
// 返回的字符串Key标识为自定义拼接的字符串内容
return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
}
return '';
onAcceptWant(want): string {
// 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
// 当前示例指的是module1 Module的SpecifiedAbility
if (want.abilityName === 'SpecifiedAbility') {
// 返回的字符串Key标识为自定义拼接的字符串内容
return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
}
return '';
}
}
```
> **说明:**
>
> 1. 当应用的UIAbility实例已经被创建,并且配置为指定实例模式时,如果再次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例,且[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md)的[onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)回调匹配到一个已创建的UIAbility实例,则系统会启动原来的UIAbility实例,并且不会重新创建一个新的UIAbility实例。此时,该UIAbility实例的[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调会被触发,而不会触发[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
> 1. 当应用的UIAbility实例已经被创建,并且配置为指定实例模式时,如果再次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例,且[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md)的[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)回调匹配到一个已创建的UIAbility实例,则系统会启动原来的UIAbility实例,并且不会重新创建一个新的UIAbility实例。此时,该UIAbility实例的[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调会被触发,而不会触发[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[`onWindowStageCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
> 2. DevEco Studio默认工程中未自动生成AbilityStage,AbilityStage文件的创建请参见[AbilityStage组件容器](abilitystage.md)。
例如在文档应用中,可以为不同的文档实例内容绑定不同的Key值。每次新建文档时,可以传入一个新的Key值(例如可以将文件的路径作为一个Key标识),此时AbilityStage中启动UIAbility时都会创建一个新的UIAbility实例;当新建的文档保存之后,回到桌面,或者新打开一个已保存的文档,回到桌面,此时再次打开该已保存的文档,此时AbilityStage中再次启动该UIAbility时,打开的仍然是之前原来已保存的文档界面。
......
......@@ -7,9 +7,8 @@
UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示。
**图1** UIAbility生命周期状态
![Ability-Life-Cycle](figures/Ability-Life-Cycle.png)
**图1** UIAbility生命周期状态
![Ability-Life-Cycle](figures/Ability-Life-Cycle.png)
## 生命周期状态说明
......@@ -17,93 +16,133 @@ UIAbility的生命周期包括Create、Foreground、Background、Destroy四个
### Create状态
Create状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI界面展示。
Create状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用`onCreate()`回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI展示。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 应用初始化
}
// ...
onCreate(want, launchParam) {
// 应用初始化
}
...
}
```
> **说明**:[Want](../reference/apis/js-apis-app-ability-want.md)是对象间信息传递的载体,可以用于应用组件间的信息传递。Want的详细介绍请参见[信息传递载体Want](want-overview.md)。
### WindowStageCreate和WindowStageDestory状态
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入onWindowStageCreate()回调,可以在该回调中设置UI界面加载、设置WindowStage的事件订阅。
**图2** WindowStageCreate和WindowStageDestory状态
UIAbility实例创建完成之后,在进入Foreground之前,系统会创建一个WindowStage。WindowStage创建完成后会进入`onWindowStageCreate()`回调,可以在该回调中设置UI加载、设置WindowStage的事件订阅。
![Ability-Life-Cycle-WindowStage](figures/Ability-Life-Cycle-WindowStage.png)
**图2** WindowStageCreate和WindowStageDestory状态
![Ability-Life-Cycle-WindowStage](figures/Ability-Life-Cycle-WindowStage.png)
在onWindowStageCreate()回调中通过loadContent()方法设置应用要加载的页面并根据需要订阅WindowStage的[事件](../reference/apis/js-apis-window.md#windowstageeventtype9)(获焦/失焦、可见/不可见)。
在onWindowStageCreate()回调中通过[`loadContent()`](../reference/apis/js-apis-window.md#loadcontent9-2)方法设置应用要加载的页面,并根据需要调用[`on('windowStageEvent')`](../reference/apis/js-apis-window.md#onwindowstageevent9)方法订阅WindowStage的[事件](../reference/apis/js-apis-window.md#windowstageeventtype9)(获焦/失焦、可见/不可见)。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: Window.WindowStage) {
// 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
// 设置UI界面加载
windowStage.loadContent('pages/Index', (err, data) => {
// ...
});
...
onWindowStageCreate(windowStage: window.WindowStage) {
// 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
try {
windowStage.on('windowStageEvent', (data) => {
let stageEventType: window.WindowStageEventType = data;
switch (stageEventType) {
case window.WindowStageEventType.SHOWN: // 切到前台
console.info('windowStage foreground.');
break;
case window.WindowStageEventType.ACTIVE: // 获焦状态
console.info('windowStage active.');
break;
case window.WindowStageEventType.INACTIVE: // 失焦状态
console.info('windowStage inactive.');
break;
case window.WindowStageEventType.HIDDEN: // 切到后台
console.info('windowStage background.');
break;
default:
break;
}
});
} catch (exception) {
console.error('Failed to enable the listener for window stage event changes. Cause:' +
JSON.stringify(exception));
}
// 设置UI加载
windowStage.loadContent('pages/Index', (err, data) => {
...
});
}
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
>
> WindowStage的相关使用请参见[窗口开发指导](../windowmanager/application-window-stage.md)。
对应于onWindowStageCreate()回调。在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI界面资源。例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件。
对应于`onWindowStageCreate()`回调。在UIAbility实例销毁之前,则会先进入`onWindowStageDestroy()`回调,可以在该回调中释放UI资源。例如在`onWindowStageDestroy()`中注销获焦/失焦等WindowStage事件。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageDestroy() {
// 释放UI界面资源
}
windowStage: window.WindowStage;
...
onWindowStageCreate(windowStage: window.WindowStage) {
this.windowStage = windowStage;
...
}
onWindowStageDestroy() {
// 释放UI资源
// 例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件
try {
this.windowStage.off('windowStageEvent');
} catch (err) {
console.error(`Failed to disable the listener for window stage event changes. Code is ${err.code}, message is ${err.message}`);
};
}
}
```
### Foreground和Background状态
Foreground和Background状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于onForeground()回调和onBackground()回调。
Foreground和Background状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于`onForeground()`回调和`onBackground()`回调。
onForeground()回调,在UIAbility的UI界面可见之前,如UIAbility切换至前台时触发。可以在onForeground()回调中申请系统需要的资源,或者重新申请在onBackground()中释放的资源。
`onForeground()`回调,在UIAbility的UI可见之前,如UIAbility切换至前台时触发。可以在`onForeground()`回调中申请系统需要的资源,或者重新申请在`onBackground()`中释放的资源。
onBackground()回调,在UIAbility的UI界面完全不可见之后,如UIAbility切换至后台时候触发。可以在onBackground()回调中释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
`onBackground()`回调,在UIAbility的UI完全不可见之后,如UIAbility切换至后台时候触发。可以在`onBackground()`回调中释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
例如应用在使用过程中需要使用用户定位时,假设应用已获得用户的定位权限授权。在UI界面显示之前,可以在onForeground()回调中开启定位功能,从而获取到当前的位置信息。
例如应用在使用过程中需要使用用户定位时,假设应用已获得用户的定位权限授权。在UI显示之前,可以在`onForeground()`回调中开启定位功能,从而获取到当前的位置信息。
当应用切换到后台状态,可以在onBackground()回调中停止定位功能,以节省系统的资源消耗。
当应用切换到后台状态,可以在`onBackground()`回调中停止定位功能,以节省系统的资源消耗。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onForeground() {
// 申请系统需要的资源,或者重新申请在onBackground中释放的资源
}
...
onBackground() {
// 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
onForeground() {
// 申请系统需要的资源,或者重新申请在onBackground()中释放的资源
}
onBackground() {
// 释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
}
```
......@@ -112,15 +151,16 @@ export default class EntryAbility extends UIAbility {
Destroy状态在UIAbility实例销毁时触发。可以在onDestroy()回调中进行系统资源的释放、数据的保存等操作。
例如调用terminateSelf()方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。
例如调用`terminateSelf()`方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onDestroy() {
// 系统资源的释放、数据的保存等
}
...
onDestroy() {
// 系统资源的释放、数据的保存等
}
}
```
......@@ -3,22 +3,25 @@
## 概述
UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。
UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。
UIAbility的设计理念:
1. 原生支持应用组件级的[跨端迁移](hop-cross-device-migration.md)[多端协同](hop-multi-device-collaboration.md)
1. 原生支持应用组件级的[跨端迁移](hop-cross-device-migration.md)[多端协同](hop-multi-device-collaboration.md)
2. 支持多设备和多窗口形态
2. 支持多设备和多窗口形态
关于UIAbility的设计理念,请详细参考[Stage模型的设计理念。](application-model-description.md)
> **说明:**
>
> 详细请参见[Stage模型的设计理念](application-model-description.md)。
UIAbility划分原则与建议:
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下
- 如果开发者希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
......@@ -32,17 +35,17 @@ UIAbility组件是系统调度的基本单元,为应用提供绘制界面的
```json
{
"module": {
// ...
...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"srcEnty": "./ets/entryability/EntryAbility.ts", // 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组件启动页面背景颜色资源文件的索引
// ...
...
}
]
}
......
......@@ -6,48 +6,47 @@ UIAbility组件的基本用法包括:指定UIAbility的启动页面以及获
## 指定UIAbility的启动页面
应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。可以在UIAbility的onWindowStageCreate()生命周期回调中,通过[WindowStage](../reference/apis/js-apis-window.md#windowstage9)对象的loadContent()方法设置启动页面。
应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。可以在UIAbility的`onWindowStageCreate()`生命周期回调中,通过[WindowStage](../reference/apis/js-apis-window.md#windowstage9)对象的`loadContent()`方法设置启动页面。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
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) => {
// ...
});
}
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
windowStage.loadContent('pages/Index', (err, data) => {
...
});
}
// ...
...
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 在DevEco Studio中创建的UIAbility中,该UIAbility实例默认会加载Index页面,根据需要将Index页面路径替换为需要的页面路径即可。
## 获取UIAbility的上下文信息
UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类的实例,[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类拥有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如startAbility()、connectServiceExtensionAbility()、terminateSelf()等)。
UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类的实例,[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类拥有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如`startAbility()``connectServiceExtensionAbility()``terminateSelf()`等)。
- 在UIAbility中可以通过this.context获取UIAbility实例的上下文信息。
- 在UIAbility中可以通过`this.context`获取UIAbility实例的上下文信息。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 获取UIAbility实例的上下文
let context = this.context;
// ...
}
onCreate(want, launchParam) {
// 获取UIAbility实例的上下文
let context = this.context;
...
}
}
```
- 在页面中获取UIAbility实例的上下文信息,包括导入依赖资源context模块和在组件中定义一个context变量两个部分。
```ts
......@@ -67,7 +66,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
// 页面展示
build() {
// ...
...
}
}
```
......@@ -92,7 +91,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
// 页面展示
build() {
// ...
...
}
}
```
......@@ -3,62 +3,51 @@
## Want的定义与用途
[Want](../reference/apis/js-apis-app-ability-want.md)对象间信息传递的载体,可以用于应用组件间的信息传递。其使用场景之一是作为startAbility()的参数,包含了指定的启动目标以及启动时需携带的相关数据,如bundleName和abilityName字段分别指明目标Ability所在应用的包名以及对应包内的Ability名称。当UIAbilityA启动UIAbilityB并需要传入一些数据给UIAbilityB时,Want可以作为一个载体将数据传给UIAbilityB
[Want](../reference/apis/js-apis-app-ability-want.md)一种对象,用于在应用组件之间传递信息
**图1** Want用法示意
其中,一种常见的使用场景是作为[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法的参数。例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。
**图1** Want用法示意
![usage-of-want](figures/usage-of-want.png)
![usage-of-want](figures/usage-of-want.png)
## Want的类型
- **显式Want**:在启动Ability时指定了abilityName和bundleName的Want称为显式Want。
当有明确处理请求的对象时,通过提供目标Ability所在应用的包名信息(bundleName),并在Want内指定abilityName便可启动目标Ability。显式Want通常用于在当前应用开发中启动某个已知的Ability。参数说明参见[Want参数说明](want-overview.md#Want参数说明)
- **显式Want**:在启动目标应用组件时,调用方传入的want参数中指定了abilityName和bundleName,称为显式Want。
显式Want通常用于在当前应用中启动已知的目标应用组件,通过提供目标应用组件所在应用的Bundle名称信息(bundleName)并在Want对象内指定abilityName来启动目标应用组件。当有明确处理请求的对象时,显式Want是一种简单有效的启动目标应用组件的方式。
```ts
let wantInfo = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
}
```
- **隐式Want**:在启动UIAbility时未指定abilityName的Want称为隐式Want。
当请求处理的对象不明确时,希望在当前应用中使用其他应用提供的某个能力(通过[skills标签](../quick-start/module-configuration-file.md#skills标签)定义),而不关心提供该能力的具体应用,可以使用隐式Want。例如使用隐式Want描述需要打开一个链接的请求,而不关心通过具体哪个应用打开,系统将匹配声明支持该请求的所有应用。
- **隐式Want**:在启动目标应用组件时,调用方传入的want参数中未指定abilityName,称为隐式Want。
当需要处理的对象不明确时,可以使用隐式Want,在当前应用中使用其他应用提供的某个能力,而不关心提供该能力的具体应用。隐式Want使用[skills标签](../quick-start/module-configuration-file.md#skills标签)来定义需要使用的能力,并由系统匹配声明支持该请求的所有应用来处理请求。例如,需要打开一个链接的请求,系统将匹配所有声明支持该请求的应用,然后让用户选择使用哪个应用打开链接。
```ts
let wantInfo = {
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.search',
// entities can be omitted
entities: [ 'entity.system.browsable' ],
uri: 'https://www.test.com:8080/query/student',
type: 'text/plain',
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.search',
// entities can be omitted
entities: [ 'entity.system.browsable' ],
uri: 'https://www.test.com:8080/query/student',
type: 'text/plain',
};
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> - 根据系统中待匹配Ability的匹配情况不同,使用隐式Want启动Ability时会出现以下三种情况。
> - 未匹配到满足条件的Ability:启动失败。
> - 匹配到一个满足条件的Ability:直接启动该Ability
> - 匹配到多个满足条件的Ability(UIAbility):弹出选择框让用户选择。
> **说明:**
> - 根据系统中待匹配应用组件的匹配情况不同,使用隐式Want启动应用组件时会出现以下三种情况。
> - 未匹配到满足条件的应用组件:启动失败。
> - 匹配到一个满足条件的应用组件:直接启动该应用组件
> - 匹配到多个满足条件的应用组件(UIAbility):弹出选择框让用户选择。
>
> - 调用方传入的want参数中不带有abilityName和bundleName,则不允许通过隐式Want启动所有应用的ServiceExtensionAbility。
>
> - 调用方传入的want参数中带有bundleName,则允许使用startServiceExtensionAbility()方法隐式Want启动ServiceExtensionAbility,默认返回优先级最高的ServiceExtensionAbility,如果优先级相同,返回第一个。
## Want参数说明
| 名称 | 读写属性 | 类型 | 必填 | 描述 |
| -------- | -------- | -------- | -------- | -------- |
| deviceId | 只读 | string | 否 | 表示目标Ability所在设备ID。如果未设置该字段,则表明本设备。 |
| bundleName | 只读 | string | 否 | 表示目标Ability所在应用名称。 |
| moduleName | 只读 | string | 否 | 表示目标Ability所属的模块名称。 |
| abilityName | 只读 | string | 否 | 表示目标Ability名称。如果未设置该字段,则该Want为隐式。如果在Want中同时指定了bundleName,moduleName和abilityName,则Want可以直接匹配到指定的Ability。 |
| uri | 只读 | string | 否 | 表示携带的数据,一般配合type使用,指明待处理的数据类型。如果在Want中指定了uri,则Want将匹配指定的Uri信息,包括scheme,&nbsp;schemeSpecificPart,&nbsp;authority和path信息。 |
| type | 只读 | string | 否 | 表示携带数据类型,使用[MIME类型](https://www.iana.org/assignments/media-types/media-types.xhtml?utm_source=ld246.com%E3%80%82)规范。例如:"text/plain"、"image/\*"等。 |
| [action](../reference/apis/js-apis-ability-wantConstant.md) | 只读 | string | 否 | 表示要执行的通用操作(如:查看、分享、应用详情)。在隐式Want中,您可定义该字段,配合uri或parameters来表示对数据要执行的操作。如打开,查看该uri数据。例如,当uri为一段网址,action为ohos.want.action.viewData则表示匹配可查看该网址的Ability。 |
| [entities](../reference/apis/js-apis-ability-wantConstant.md) | 只读 | Array&lt;string&gt; | 否 | 表示目标Ability额外的类别信息(如:浏览器,视频播放器),在隐式Want中是对action的补充。在隐式Want中,您可定义该字段,来过滤匹配UIAbility类别,如必须是浏览器。例如,在action字段的举例中,可存在多个应用声明了支持查看网址的操作,其中有应用为普通社交应用,有的为浏览器应用,您可通过entity.system.browsable过滤掉非浏览器的其他应用。 |
| [flags](../reference/apis/js-apis-ability-wantConstant.md#wantconstantflags) | 只读 | number | 否 | 表示处理Want的方式。例如通过wantConstant.Flags.FLAG_ABILITY_CONTINUATION表示是否以设备间迁移方式启动Ability。 |
| parameters | 只读 | {[key:&nbsp;string]:&nbsp;any} | 否 | 此参数用于传递自定义数据,通过用户自定义的键值对进行数据填充,具体支持的数据类型如[Want&nbsp;API](../reference/apis/js-apis-app-ability-want.md)所示。 |
......@@ -11,7 +11,7 @@
| 配置项 | FA模型 | Stage模型 |
| ---------------- | ------------------------------------------- | ------------------------------------------------------------ |
| 配置项位置 | formAbility和forms配置都在config.json文件里 | 一级目录module.json5配置文件中配置extensionAbilities(针对formExtensionAbility的配置),二级目录form_config.json文件中配置forms(针对formExtensionAbility里包含的forms的详细配置) |
| 卡片代码路径 | srcPath,不带文件名 | srcEnty,带文件名 |
| 卡片代码路径 | srcPath,不带文件名 | srcEntry,带文件名 |
| 语言 | srcLanguage支持配置为js或ets | 无此配置项,只支持ets |
| 是否使能卡片 | formsEnabled | 无,type配置项配置为form即使能 |
| ability类型 | type:service | type:form |
......@@ -32,7 +32,7 @@
| 入口及生命周期 | FA模型 | Stage模型 |
| -------- | -------- | -------- |
| 入口文件 | srcPath指向的目录下的form.ts | srcEnty指向的文件 |
| 入口文件 | srcPath指向的目录下的form.ts | srcEntry指向的文件 |
| 生命周期 | export&nbsp;default | import&nbsp;FormExtension&nbsp;from&nbsp;'\@ohos.app.form.FormExtensionAbility';<br/>export&nbsp;default&nbsp;class&nbsp;FormAbility&nbsp;extends&nbsp;FormExtension |
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册