未验证 提交 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.');
......
......@@ -24,8 +24,8 @@ app.json5中对原先config.json中的[deviceConfig](../quick-start/deviceconfig
| FA中deviceConfig标签 | 描述 | stage模型中 | 差异比对 |
| -------- | -------- | -------- | -------- |
| deviceConfig标签 | deviceConfig标签配置了设备信息 | / | Stage模型中没有该标签,直接在app标签下配置设备信息 |
| process | 标识应用或者Ability的进程名。如果在deviceConfig标签下配置了process标签,则该应用的所有Ability都运行在这个进程中。如果在abilities标签下也为某个Ability配置了process标签,则该Ability就运行在这个进程中。 | / | Stage模型不支持配置进程名称 |
| process | 标识应用或者UIAbility的进程名。如果在deviceConfig标签下配置了process标签,则该应用的所有UIAbility都运行在这个进程中。如果在abilities标签下也为某个UIAbility配置了process标签,则该UIAbility就运行在这个进程中。 | / | Stage模型不支持配置进程名称 |
| keepAlive | 标识应用是否始终保持运行状态,仅支持系统应用配置,三方应用配置不生效。 | / | Stage模型不支持系统应用模型管控方式变更 |
| supportBackup | 标识应用是否支持备份和恢复。 | / | Stage模型不支持 |
| compressNativeLibs | 标识libs库是否以压缩存储的方式打包到HAP包。 | / | Stage模型不支持 |
| compressNativeLibs | 标识libs库是否以压缩存储的方式打包到HAP。 | / | Stage模型不支持 |
| network | 标识网络安全性配置。 | / | Stage模型不支持 |
# 应用/组件级配置
开发者在开发应用时,需要配置应用的一些标签,例如应用的包名、图标等标识特征的属性。这一章节描述了开发者在开发应用时需要配置的一些关键标签。
开发者在开发应用时,需要配置应用的一些标签,例如应用的Bundle名称、图标等标识特征的属性。这一章节描述了开发者在开发应用时需要配置的一些关键标签。
- **应用包名配置**
......@@ -22,7 +22,7 @@
"actions": ["action.system.home"]
}
]
// ...
...
}
```
......
# 应用/组件级配置
在开发应用时,需要配置应用的一些标签,例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。
在开发应用时,需要配置应用的一些标签,例如应用的包名、图标等标识特征的属性。本文描述了在开发应用需要配置的一些关键标签。图标和标签通常一起配置,可以分为应用图标、应用标签和入口图标、入口标签,分别对应[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)
- **应用包名配置**
......@@ -26,7 +27,7 @@
"app": {
"icon": "$media:app_icon",
"label": "$string:app_name"
// ...
...
}
}
```
......@@ -40,7 +41,7 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// $开头的为资源值
......
......@@ -6,11 +6,9 @@
[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-inheritance](figures/context-inheritance.png)
- 各类Context的持有关系
![context-holding](figures/context-holding.png)
- 各类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中获取的应用开发路径
![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';
......
......@@ -3,17 +3,14 @@
在已有的应用工程中,创建ArkTS卡片,具体的操作方式如下。
1. 创建卡片。
![WidgetProjectCreate1](figures/WidgetProjectCreate1.png)
2. 根据实际业务场景,选择一个卡片模板。
![WidgetProjectCreate2](figures/WidgetProjectCreate2.png)
3. 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单击“Finish”,即可完成ArkTS卡片创建。
![WidgetProjectCreate3](figures/WidgetProjectCreate3.png)
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)。
![WidgetProjectView](figures/WidgetProjectView.png)
![WidgetProjectView](figures/WidgetProjectView.png)
\ No newline at end of file
......@@ -55,12 +55,12 @@
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;
}
......@@ -72,7 +72,7 @@
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
console.error(`Failed to register callee on. Cause: ${JSON.stringify(err)}`);
}
}
......@@ -81,8 +81,8 @@
try {
this.callee.off('funA');
this.callee.off('funB');
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
} 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三种类型的事件,仅在卡片中可以调用。
![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能力,能够快速拉起卡片提供方应用,因此页面较多的应用往往会通过卡片提供不同的跳转按钮,实现一键直达的效果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机应用的不同页面,从而提高用户的体验。
![WidgerCameraCard](figures/WidgerCameraCard.png)
......
......@@ -150,7 +150,7 @@
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) {
......@@ -180,7 +180,7 @@
// 监听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)}`)
}
}
...
......
......@@ -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()接口主动触发卡片的页面刷新。
![WidgetLocalStorageProp](figures/WidgetLocalStorageProp.png)
......
......@@ -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模板自动生成,开发者可以根据自身的业务场景进行调整。
![WidgetPreviewPage](figures/WidgetPreviewPage.png)
......@@ -17,6 +14,5 @@ ArkTS卡片支持的页面能力详见[学习ArkTS语言](../quick-start/arkts-c
只有标识“支持在ArkTS卡片中使用”的接口可用于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,9 +25,10 @@
卡片作为应用的一个快捷入口,ArkTS卡片相较于JS卡片具备如下几点优势:
- 统一开发范式,提升开发体验和开发效率。
OpenHarmony在2022年发布了声明式范式的UI开发框架,而卡片还延续了css/hml/json三段式类Web范式的开发方式,提高了开发者的学习成本,提供ArkTS卡片能力后,统一了卡片和页面的开发范式,页面的布局可以直接复用到卡片布局中,提升开发体验和开发效率。
**图3** 卡片工程结构对比  
**图3** 卡片工程结构对比
![WidgetProject](figures/WidgetProject.png)
- 增强了卡片的能力,使卡片更加万能。
......
......@@ -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);
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)文档介绍。
......@@ -40,14 +40,14 @@
```ts
// 创建订阅者回调
commonEvent.createSubscriber(subscribeInfo, (err, data) => {
commonEventManager.createSubscriber(subscribeInfo, (err, data) => {
if (err) {
console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] CreateSubscriber success`);
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) => {
commonEventManager.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`);
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)进行相应操作。
......
......@@ -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"
}
]
```
......
# 显式Want与隐式Want匹配规则
在启动目标Ability时,会通过显式Want和隐式Want进行目标Ability的匹配,这里说的匹配规则就是调用方Want中设置的参数如何与目标Ability声明的配置文件进行匹配。
- **显式Want匹配原理**
| 名称 | 类型 | 匹配项 | 必选 | 规则 |
| -------- | -------- | -------- | -------- | -------- |
| deviceId | string | 是 | 否 | 留空将仅匹配本设备内Ability。 |
| bundleName | string | 是 | 是 | 如果指定abilityName,而不指定bundleName,则匹配失败。 |
| moduleName | string | 是 | 否 | 留空时当同一个应用内存在多个模块且模块间存在重名Ability,将默认匹配第一个。 |
| abilityName | string | 是 | 是 | 该字段必须设置表示显式匹配。 |
| uri | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| type | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| action | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| entities | Array&lt;string&gt; | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| flags | number | 否 | 否 | 不参与匹配,直接传递给系统处理,一般用来设置运行态信息,例如URI数据授权等。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标Ability。 |
- **隐式Want匹配原理**
| 名称 | 类型 | 匹配项 | 必选 | 规则 |
| -------- | -------- | -------- | -------- | -------- |
| deviceId | string | 是 | 否 | 跨设备目前不支持隐式调用。 |
| abilityName | string | 否 | 否 | 该字段必须留空表示隐式匹配。 |
| bundleName | string | 是 | 否 | -&nbsp;声明bundleName时,隐式搜索将仅限于对应应用包内。<br/>-&nbsp;声明bundleName与moduleName时,隐式搜索将仅限于对应应用的对应Module内。<br/>-&nbsp;单独声明moduleName时,该字段无效。<br/>-&nbsp;同时声明bundleName与moduleName时,隐式搜索将仅限于对应应用包内的对应模块内。<br/>这些字段将用来隐式匹配,具体规则可参考[隐式Want匹配原理详解](#隐式want匹配原理详解)。 |
| moduleName | string | 是 | 否 |
| uri | string | 是 | 否 |
| type | string | 是 | 否 |
| action | string | 是 | 否 |
| entities | Array&lt;string&gt; | 是 | 否 |
| flags | number | 否 | 否 | 不参与匹配,直接传递给系统处理,一般用来设置运行态信息,例如URI数据授权等。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标Ability。 |
## 隐式Want匹配原理详解
在启动目标应用组件时,会通过显式[Want](../reference/apis/js-apis-app-ability-want.md)或者隐式[Want](../reference/apis/js-apis-app-ability-want.md)进行目标应用组件的匹配,这里说的匹配规则就是调用方传入的[want](../reference/apis/js-apis-app-ability-want.md)参数中设置的参数如何与目标应用组件声明的配置文件进行匹配。
## 显式Want匹配原理
显式[Want](../reference/apis/js-apis-app-ability-want.md)匹配原理如下表所示。
| 名称 | 类型 | 匹配项 | 必选 | 规则 |
| -------- | -------- | -------- | -------- | -------- |
| deviceId | string | 是 | 否 | 留空将仅匹配本设备内的应用组件。 |
| bundleName | string | 是 | 是 | 如果指定abilityName,而不指定bundleName,则匹配失败。 |
| moduleName | string | 是 | 否 | 留空时当同一个应用内存在多个模块且模块间存在重名应用组件,将默认匹配第一个。 |
| abilityName | string | 是 | 是 | 该字段必须设置表示显式匹配。 |
| uri | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| type | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| action | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| entities | Array&lt;string&gt; | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| flags | number | 否 | 否 | 不参与匹配,直接传递给系统处理,一般用来设置运行态信息,例如URI数据授权等。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标应用组件。 |
## 隐式Want匹配原理
隐式[Want](../reference/apis/js-apis-app-ability-want.md)匹配原理如下表所示。
| 名称 | 类型 | 匹配项 | 必选 | 规则 |
| ----------- | ------------------------------ | ------ | ---- | ------------------------------------------------------------ |
| deviceId | string | 是 | 否 | 跨设备目前不支持隐式调用。 |
| abilityName | string | 否 | 否 | 该字段必须留空表示隐式匹配。 |
| bundleName | string | 是 | 否 | -&nbsp;声明bundleName时,隐式搜索将仅限于对应应用包内。<br/>-&nbsp;声明bundleName与moduleName时,隐式搜索将仅限于对应应用的对应Module内。<br/>-&nbsp;单独声明moduleName时,该字段无效。<br/>-&nbsp;同时声明bundleName与moduleName时,隐式搜索将仅限于对应应用包内的对应模块内。<br/>这些字段将用来隐式匹配。 |
| moduleName | string | 是 | 否 | |
| uri | string | 是 | 否 | |
| type | string | 是 | 否 | |
| action | string | 是 | 否 | |
| entities | Array&lt;string&gt; | 是 | 否 | |
| flags | number | 否 | 否 | 不参与匹配,直接传递给系统处理,一般用来设置运行态信息,例如URI数据授权等。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标应用组件。 |
从隐式Want的定义,可得知:
- 调用方传入的want参数,表明调用方需要执行的操作,并提供相关数据以及其他应用类型限制。
- 待匹配Ability的skills配置,声明其具备的能力([module.json5配置文件](../quick-start/module-configuration-file.md)中的[skills标签](../quick-start/module-configuration-file.md#skills标签)参数)。
- 待匹配应用组件的skills配置,声明其具备的能力([module.json5配置文件](../quick-start/module-configuration-file.md)中的[skills标签](../quick-start/module-configuration-file.md#skills标签)参数)。
系统将调用方传入的want参数(包含action、entities、uri和type属性)与已安装待匹配的应用Ability的skills配置(包含actions、entities、uris和type属性)依次进行匹配。当四个属性匹配均通过,则此应用才会被应用选择器展示给用户进行选择。
系统将调用方传入的want参数(包含action、entities、uri和type属性)与已安装待匹配应用组件的skills配置(包含actions、entities、uris和type属性)依次进行匹配。当四个属性匹配均通过,则此应用才会被应用选择器展示给用户进行选择。
### want参数的action匹配规则
将调用方传入的want参数的action与待匹配Ability的skills配置中的actions进行匹配。
将调用方传入的want参数的action与待匹配应用组件的skills配置中的actions进行匹配。
- 调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions为空,则action匹配失败。
- 调用方传入的want参数的action不为空,待匹配应用组件的skills配置中的actions为空,则action匹配失败。
- 调用方传入的want参数的action为空,待匹配Ability的skills配置中的actions不为空,则action匹配成功。
- 调用方传入的want参数的action为空,待匹配应用组件的skills配置中的actions不为空,则action匹配成功。
- 调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions不为空且包含调用方传入的want参数的action,则action匹配成功。
- 调用方传入的want参数的action不为空,待匹配应用组件的skills配置中的actions不为空且包含调用方传入的want参数的action,则action匹配成功。
- 调用方传入的want参数的action不为空,待匹配Ability的skills配置中的actions不为空且不包含调用方传入的want参数的action,则action匹配失败。
- 调用方传入的want参数的action不为空,待匹配应用组件的skills配置中的actions不为空且不包含调用方传入的want参数的action,则action匹配失败。
**图1** want参数的action匹配规则
![want-action](figures/want-action.png)
![want-action](figures/want-action.png)
### want参数的entities匹配规则
将调用方传入的want参数的entities与待匹配Ability的skills配置中的entities进行匹配。
将调用方传入的want参数的entities与待匹配应用组件的skills配置中的entities进行匹配。
- 调用方传入的want参数的entities为空,待匹配Ability的skills配置中的entities不为空,则entities匹配成功。
- 调用方传入的want参数的entities为空,待匹配应用组件的skills配置中的entities不为空,则entities匹配成功。
- 调用方传入的want参数的entities为空,待匹配Ability的skills配置中的entities为空,则entities匹配成功。
- 调用方传入的want参数的entities为空,待匹配应用组件的skills配置中的entities为空,则entities匹配成功。
- 调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities为空,则entities匹配失败。
- 调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities为空,则entities匹配失败。
- 调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities不为空且包含调用方传入的want参数的entities,则entities匹配成功。
- 调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities不为空且包含调用方传入的want参数的entities,则entities匹配成功。
- 调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities不为空且不完全包含调用方传入的want参数的entities,则entities匹配失败。
- 调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities不为空且不完全包含调用方传入的want参数的entities,则entities匹配失败。
**图2** want参数的entities匹配规则
![want-entities](figures/want-entities.png)
![want-entities](figures/want-entities.png)
### want参数的uri和type匹配规则
调用方传入的want参数中设置uri和type参数发起组件启动请求,系统会遍历当前系统已安装的组件列表,并逐个匹配待匹配Ability的skills配置中的uris数组,如果待匹配Ability的skills配置中的uris数组中只要有一个可以匹配调用方传入的want参数中设置的uri和type即为匹配成功。
调用方传入的want参数中设置uri和type参数发起启动应用组件的请求,系统会遍历当前系统已安装的组件列表,并逐个匹配待匹配应用组件的skills配置中的uris数组,如果待匹配应用组件的skills配置中的uris数组中只要有一个可以匹配调用方传入的want参数中设置的uri和type即为匹配成功。
实际应用中,uri和type共存在四种情况,下面将讲解四种情况的具体匹配规则:
- 调用方传入的want参数的uri和type都为空。
1. 如果待匹配Ability的skills配置中的uris数组为空,匹配成功。
2. 如果待匹配Ability的skills配置中的uris数组中存在uri的scheme和type都为空的元素,匹配成功。
1. 如果待匹配应用组件的skills配置中的uris数组为空,匹配成功。
2. 如果待匹配应用组件的skills配置中的uris数组中存在uri的scheme和type都为空的元素,匹配成功。
3. 除以上两种情况,其他情况均为匹配失败。
- 调用方传入的want参数的uri不为空,type为空。
1. 如果待匹配Ability的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配Ability的skills配置中的uris数组存在一条数据[uri匹配](#uri匹配规则)成功且type为空,则匹配成功,否则匹配失败。
1. 如果待匹配应用组件的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配应用组件的skills配置中的uris数组存在一条数据[uri匹配](#uri匹配规则)成功且type为空,则匹配成功,否则匹配失败。
- 调用方传入的want参数的uri为空,type不为空。
1. 如果待匹配Ability的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配Ability的skills配置中的uris数组存在一条数据uri的scheme为空且[type匹配](#type匹配规则)成功,则匹配成功,否则匹配失败。
- 调用方传入的want参数的uri和type都不为空,如图3所示。
1. 如果待匹配Ability的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配Ability的skills配置中的uris数组存在一条数据[uri匹配](#uri匹配规则)[type匹配](#type匹配规则)需要均匹配成功,则匹配成功,否则匹配失败。
1. 如果待匹配应用组件的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配应用组件的skills配置中的uris数组存在一条数据uri的scheme为空且[type匹配](#type匹配规则)成功,则匹配成功,否则匹配失败。
最左uri匹配:当配置文件待匹配Ability的skills配置中的uris数组中只配置scheme;或者只配置scheme和host;或者只配置scheme,host和port时。
传入want参数的uri的最左边依次需要和scheme;或者scheme和host;或者scheme,host,port都匹配,才满足最左uri匹配。
- 调用方传入的want参数的uri和type都不为空,如下图所示。
1. 如果待匹配应用组件的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配应用组件的skills配置中的uris数组存在一条数据[uri匹配](#uri匹配规则)[type匹配](#type匹配规则)需要均匹配成功,则匹配成功,否则匹配失败。
**图3** want参数中uri和type皆不为空时的匹配规则
最左uri匹配:当配置文件待匹配应用组件的skills配置中的uris数组中只配置scheme;或者只配置scheme和host;或者只配置scheme、host和port时。传入want参数的uri的最左边依次需要和scheme,或者scheme和host,或者scheme、host和port都匹配,才满足最左uri匹配。
![want-uri-type1](figures/want-uri-type1.png)
**图3** want参数中uri和type皆不为空时的匹配规则
![want-uri-type1](figures/want-uri-type1.png)
下图为了简化描述,称want中传入的uri为w_uri,称want中传入的type为w_type, 待匹配Ability的skills配置中uris为s_uris,其中每个元素为s_uri;按自上而下顺序匹配。
为了简化描述:
- 称调用方传入的want参数中的uri参数为w_uri;待匹配应用组件的skills配置中uri为s_uri,其中每个元素为s_uri。
- 称调用方传入的want参数的type参数为w_type,待匹配应用组件的skills数组中uris的type数据为s_type。
**图4** want参数中uri和type的具体匹配规则
**图4** want参数中uri和type的具体匹配规则
![want-uri-type2](figures/want-uri-type2.png)
### uri匹配规则
这里为了简化描述,称want中传入的uri为w_uri,待匹配Ability的skills配置中uri为s_uri,具体的匹配规则如下:
具体的匹配规则如下:
- 如果s_uri的scheme为空,当w_uri为空时匹配成功,否则匹配失败
- 如果s_uri的scheme为空,当w_uri为空时匹配成功,否则匹配失败
- 如果s_uri的host为空,当w_uri和s_uri的scheme相同时匹配成功,否则匹配失败
- 如果s_uri的host为空,当w_uri和s_uri的scheme相同时匹配成功,否则匹配失败
- 如果s_uri的port为空,当w_uri和s_uri中的scheme和host相同时匹配成功,否则匹配失败
- 如果s_uri的port为空,当w_uri和s_uri中的scheme和host相同时匹配成功,否则匹配失败
- 如果s_uri的path、pathStartWith和pathRegex都为空,当w_uri和s_uri中的scheme,host和port相同时匹配成功,否则匹配失败
- 如果s_uri的path、pathStartWith和pathRegex都为空,当w_uri和s_uri中的scheme,host和port相同时匹配成功,否则匹配失败
- 如果s_uri的path不为空,当w_uri和s_uri**全路径表达式**相同时匹配成功,否则继续进行pathStartWith的匹配
- 如果s_uri的path不为空,当w_uri和s_uri**全路径表达式**相同时匹配成功,否则继续进行pathStartWith的匹配
- 如果s_uri的pathStartWith不为空,当w_uri包含s_uri**前缀表达式**时匹配成功,否则继续进行pathRegex的匹配
- 如果s_uri的pathStartWith不为空,当w_uri包含s_uri**前缀表达式**时匹配成功,否则继续进行pathRegex的匹配
- 如果s_uri的pathRegex不为空,当w_uri满足s_uri**正则表达式**时匹配成功,否则匹配失败
- 如果s_uri的pathRegex不为空,当w_uri满足s_uri**正则表达式**时匹配成功,否则匹配失败
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 待匹配Ability的skills配置的uris中scheme、host、port、path、pathStartWith和pathRegex属性拼接,如果依次声明了path、pathStartWith和pathRegex属性时,uris将分别拼接为如下三种表达式:
>
> - **全路径表达式**:scheme://host:port/path
>
> - **前缀表达式**:scheme://host:port/pathStartWith
> **说明:**
>
> - **正则表达式**:scheme://host:port/pathRegex
> 待匹配应用组件的skills配置的uris中scheme、host、port、path、pathStartWith和pathRegex属性拼接,如果依次声明了path、pathStartWith和pathRegex属性时,uris将分别拼接为如下三种表达式:
>
> - **前缀uri表达式**:当配置文件只配置scheme,或者只配置scheme和host,或者只配置scheme,host和port时,参数传入以配置文件为前缀的Uri
> * `scheme://`
> * `scheme://host`
> * `scheme://host:port`
> - **全路径表达式**:`scheme://host:port/path`
> - **前缀表达式**:`scheme://host:port/pathStartWith`
> - **正则表达式**:`scheme://host:port/pathRegex`
### type匹配规则
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 此小节所述的type匹配规则的适用性需建立在want参数内type不为空的基础上。当want参数内type为空时请参考[want参数的uri和type匹配规则](#want参数的uri和type匹配规则)。
> **说明:**
>
> 本章节所述的type匹配规则的适用性需建立在want参数内type不为空的基础上。当want参数内type为空时请参见[want参数的uri和type匹配规则](#want参数的uri和type匹配规则)。
这里为了简化描述,称want中传入的uri为w_type,待匹配Ability的skills数组中uris的type数据为s_type,具体的匹配规则如下:
具体的匹配规则如下:
- 如果s_type为空,则匹配失败。
- 如果s_type或者w_type为通配符"\*/\*",则匹配成功。
- 如果s_type或者w_type为通配符`*/*`,则匹配成功。
- 如果s_type最后一个字符为通配符'\*',如"prefixType/\*",则当w_type包含"prefixType/"时匹配成功,否则匹配失败。
- 如果s_type最后一个字符为通配符`*`,如`prefixType/*`,则当w_type包含`prefixType/`时匹配成功,否则匹配失败。
- 如果w_type最后一个字符为通配符'\*',如"prefixType/\*",则当s_type包含"prefixType/"时匹配成功,否则匹配失败。
- 如果w_type最后一个字符为通配符`*`,如`prefixType/*`,则当s_type包含`prefixType/`时匹配成功,否则匹配失败。
......@@ -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)
......@@ -48,11 +48,10 @@ 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进行调度管理。
![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。则该应用在运行时,有三个进程:
......
......@@ -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个。
......@@ -12,7 +12,7 @@
- MissionListManager:系统任务管理模块,内部维护了当前所有的任务链,与最近任务列表保持一致。
**图1** 任务管理示意图  
**图1** 任务管理示意图
![mission-list-manager](figures/mission-list-manager.png)
......@@ -28,20 +28,16 @@
- 将一个指定的任务切换到前台。
一个UIAbility实例对应一个单独的任务,因此应用调用startAbility()方法启动一个UIAbility时,就是创建了一个任务。
一个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#配置文件权限声明)
桌面应用调用[missionManager](../reference/apis/js-apis-application-missionManager.md)的接口管理任务,需要申请`ohos.permission.MANAGE_MISSIONS`权限,配置方式请参阅[访问控制授权申请指导](../security/accesstoken-guidelines.md#stage模型)
2. 利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等)
```ts
import missionManager from '@ohos.app.ability.missionManager'
利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等),示例代码如下:
```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
let listener = {
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
......@@ -70,62 +66,64 @@ let listener = {
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
};
// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);
// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);
// 2.获取系统最近20个任务
missionManager.getMissionInfos("", 20, (error, missions) => {
// 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) {
// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
});
});
// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
// 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) => {
// 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(() => {
// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
});
});
missionManager.unlockMission(missionId).then(() => {
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
});
});
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
});
});
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
});
});
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
});
});
// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
// 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管理)
......
......@@ -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卡片。
# ServiceExtensionAbility
- [ServiceExtensionAbility](#serviceextensionability)
- [概述](#概述)
- [生命周期](#生命周期)
- [实现一个后台服务(仅对系统应用开放)](#实现一个后台服务仅对系统应用开放)
- [概述](#概述)
- [生命周期](#生命周期)
- [实现一个后台服务(仅对系统应用开放)](#实现一个后台服务仅对系统应用开放)
- [开发准备](#开发准备)
- [定义IDL接口](#定义idl接口)
- [创建ServiceExtensionAbility](#创建serviceextensionability)
- [启动一个后台服务(仅对系统应用开放)](#启动一个后台服务仅对系统应用开放)
- [连接一个后台服务](#连接一个后台服务)
- [客户端与服务端通信](#客户端与服务端通信)
- [服务端对客户端身份校验](#服务端对客户端身份校验)
- [相关实例](#相关实)
- [启动一个后台服务(仅对系统应用开放)](#启动一个后台服务仅对系统应用开放)
- [连接一个后台服务](#连接一个后台服务)
- [客户端与服务端通信](#客户端与服务端通信)
- [服务端对客户端身份校验](#服务端对客户端身份校验)
- [相关示例](#相关示)
## 概述
......@@ -31,7 +30,8 @@
- Service一旦通过start的方式被拉起,将不会自动退出,系统应用可以调用[stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstopserviceextensionability)方法将Service退出。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
>
> 1. OpenHarmony当前不支持三方应用实现ServiceExtensionAbility。如果三方开发者想要实现后台处理相关事务的功能,可以使用后台任务,具体请参见[后台任务](../task-management/background-task-overview.md)。
> 2. 三方应用的UIAbility组件可以通过Context连接系统提供的ServiceExtensionAbility。
> 3. 三方应用需要在前台获焦的情况下才能连接系统提供的ServiceExtensionAbility。
......@@ -46,7 +46,7 @@
- **onCreate**
服务被首次创建时触发该回调,开发者可以在此进行一些初始化的操作,例如注册公共事件监听等。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 如果服务已创建,再次启动该ServiceExtensionAbility不会触发onCreate()回调。
- **onRequest**
......@@ -115,7 +115,7 @@ export default class ServiceExtImpl extends IdlServiceExtStub {
insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void {
// 开发者自行实现业务逻辑
console.log(TAG, `insertDataToMap, key: ${key} val: ${val}`);
console.info(TAG, `insertDataToMap, key: ${key} val: ${val}`);
callback(ERR_OK);
}
}
......@@ -181,7 +181,7 @@ export default class ServiceExtImpl extends IdlServiceExtStub {
```json
{
"module": {
// ...
...
"extensionAbilities": [
{
"name": "ServiceExtAbility",
......@@ -200,52 +200,53 @@ export default class ServiceExtImpl extends IdlServiceExtStub {
系统应用通过[startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability)方法启动一个后台服务,服务的[onRequest()](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonrequest)回调就会被调用,并在该回调方法中接收到调用者传递过来的want对象。后台服务启动后,其生命周期独立于客户端,即使客户端已经销毁,该后台服务仍可继续运行。因此,后台服务需要在其工作完成时通过调用ServiceExtensionContext的[terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself)来自行停止,或者由另一个组件调用[stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability)来将其停止。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> ServiceExtensionContext的[startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability)、[stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability)和[terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself)为系统接口,三方应用不支持调用。
1. 在系统应用中启动一个新的ServiceExtensionAbility。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let context = ...; // UIAbilityContext
let want = {
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "ServiceExtAbility"
};
this.context.startServiceExtensionAbility(want).then(() => {
console.info('startServiceExtensionAbility success');
}).catch((error) => {
console.info('startServiceExtensionAbility failed');
context.startServiceExtensionAbility(want).then(() => {
console.info('Succeeded in starting ServiceExtensionAbility.');
}).catch((err) => {
console.error(`Failed to start ServiceExtensionAbility. Code is ${err.code}, message is ${err.message}`);
})
```
2. 在系统应用中停止一个已启动的ServiceExtensionAbility。
```ts
let context = ...; // UIAbilityContext
let want = {
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "ServiceExtAbility"
};
this.context.stopServiceExtensionAbility(want).then(() => {
console.info('stopServiceExtensionAbility success');
}).catch((error) => {
console.info('stopServiceExtensionAbility failed');
context.stopServiceExtensionAbility(want).then(() => {
console.info('Succeeded in stoping ServiceExtensionAbility.');
}).catch((err) => {
console.error(`Failed to stop ServiceExtensionAbility. Code is ${err.code}, message is ${err.message}`);
})
```
3. 已启动的ServiceExtensionAbility停止自身。
```ts
// this是当前ServiceExtensionAbility
this.context.terminateSelf().then(() => {
console.info('terminateSelf success');
}).catch((error) => {
console.info('terminateSelf failed');
let context = ...; // ServiceExtensionContext
context.terminateSelf().then(() => {
console.info('Succeeded in terminating self.');
}).catch((err) => {
console.error(`Failed to terminate self. Code is ${err.code}, message is ${err.message}`);
})
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 后台服务可以在后台长期运行,为了避免资源浪费,需要对后台服务的生命周期进行管理。即一个后台服务完成了请求方的任务,需要及时销毁。销毁已启动的后台服务有两种方式:
>
> - 后台服务自身调用[terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself)方法来自行停止。
......@@ -258,7 +259,7 @@ export default class ServiceExtImpl extends IdlServiceExtStub {
ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonconnect)中返回IRemoteObject对象,开发者通过该IRemoteObject定义通信接口,用于客户端与服务端进行RPC交互。多个客户端可以同时连接到同一个后台服务,客户端完成与服务的交互后,客户端需要通过调用[disconnectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability)来断开连接。如果所有连接到某个后台服务的客户端均已断开连接,则系统会销毁该服务。
- 使用connectServiceExtensionAbility()建立与后台服务的连接。示例中的context的获取方式参见[获取UIAbility的Context属性](uiability-usage.md#获取uiability的上下文信息)
- 使用connectServiceExtensionAbility()建立与后台服务的连接。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let want = {
......@@ -319,10 +320,10 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
let serviceExtProxy = new IdlServiceExtProxy(remote);
// 通过接口调用的方式进行通信,屏蔽了RPC通信的细节,简洁明了
serviceExtProxy.processData(1, (errorCode, retVal) => {
console.log(`processData, errorCode: ${errorCode}, retVal: ${retVal}`);
console.info(`processData, errorCode: ${errorCode}, retVal: ${retVal}`);
});
serviceExtProxy.insertDataToMap('theKey', 1, (errorCode) => {
console.log(`insertDataToMap, errorCode: ${errorCode}`);
console.info(`insertDataToMap, errorCode: ${errorCode}`);
})
},
onDisconnect(elementName) {
......@@ -386,8 +387,8 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
```ts
import rpc from '@ohos.rpc';
import bundleManager from '@ohos.bundle.bundleManager';
import {processDataCallback} from './i_idl_service_ext';
import {insertDataToMapCallback} from './i_idl_service_ext';
import { processDataCallback } from './i_idl_service_ext';
import { insertDataToMapCallback } from './i_idl_service_ext';
import IdlServiceExtStub from './idl_service_ext_stub';
const ERR_OK = 0;
......@@ -414,7 +415,7 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void {
// 开发者自行实现业务逻辑
console.log(TAG, `insertDataToMap, key: ${key} val: ${val}`);
console.info(TAG, `insertDataToMap, key: ${key} val: ${val}`);
callback(ERR_OK);
}
}
......@@ -454,15 +455,15 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void {
// 开发者自行实现业务逻辑
console.log(TAG, `insertDataToMap, key: ${key} val: ${val}`);
console.info(TAG, `insertDataToMap, key: ${key} val: ${val}`);
callback(ERR_OK);
}
}
```
## 相关
## 相关
针对ServiceExtensionAbility开发,有以下相关例可供参考:
针对ServiceExtensionAbility开发,有以下相关例可供参考:
- [`AbilityConnectServiceExtension`:Ability与ServiceExtensionAbility通信(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/code/BasicFeature/IDL/AbilityConnectServiceExtension)
- [`StageModel`:Stage模型(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/code/BasicFeature/ApplicationModels/StageModel)
- [`AbilityConnectServiceExtension`:Ability与ServiceExtensionAbility通信(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension)
- [`StageModel`:Stage模型(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
......@@ -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.');
......
......@@ -88,7 +88,9 @@ async function RequestPermission() {
```ts
import deviceManager from '@ohos.distributedHardware.deviceManager';
let dmClass;
function getDeviceManager() {
deviceManager.createDeviceManager('ohos.example.distributedService', (error, dm) => {
if (error) {
......@@ -97,17 +99,18 @@ function getDeviceManager() {
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");
console.info("EntryAbility onButtonClick getRemoteDeviceId err: list is null");
return;
}
console.info("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
console.info("EntryAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
return list[0].deviceId;
} else {
console.info("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null");
console.info("EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null");
}
}
```
......@@ -120,6 +123,7 @@ function getRemoteDeviceId() {
```ts
import featureAbility from '@ohos.ability.featureAbility';
function onStartRemoteAbility() {
console.info('onStartRemoteAbility begin');
let params;
......
......@@ -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';
......@@ -41,7 +40,7 @@ EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,
}
```
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;
// ...
...
}
// ...
...
}
```
2. 在UI界面中即可通过globalThis获取到want参数信息。
2. 在UI中即可通过globalThis获取到want参数信息。
```ts
let entryAbilityWant;
......@@ -136,7 +133,7 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
// 页面展示
build() {
// ...
...
}
}
```
......@@ -144,31 +141,31 @@ 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 {
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.entryAbilityStr = 'AbilityA'; // AbilityA存放字符串“AbilityA”到globalThis
// ...
globalThis.entryAbilityStr = 'UIAbilityA'; // UIAbilityA存放字符串“UIAbilityA”到globalThis
...
}
}
```
2. AbilityB中获取对应的数据。
2. UIAbilityB中获取对应的数据。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class AbilityB extends UIAbility {
export default class UIAbilityB extends UIAbility {
onCreate(want, launch) {
// AbilityB从globalThis读取name并输出
// UIAbilityB从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
// ...
...
}
}
```
......@@ -176,18 +173,18 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
### 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 {
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
// AbilityA存放字符串“AbilityA”到globalThis
globalThis.entryAbilityStr = 'AbilityA';
// ...
// UIAbilityA存放字符串“UIAbilityA”到globalThis
globalThis.entryAbilityStr = 'UIAbilityA';
...
}
}
```
......@@ -201,7 +198,7 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
onCreate(want) {
// ServiceExtAbility从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
// ...
...
}
}
```
......@@ -209,11 +206,10 @@ globalThis为[ArkTS引擎实例](thread-model-stage.md)下的全局对象,可
### 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 {
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.context = this.context; // AbilityA存放context到globalThis
// ...
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 {
export default class UIAbilityB extends UIAbility {
onCreate(want, launch) {
// AbilityB覆盖了AbilityA在globalThis中存放的context
// 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从后台进入前台,不会再走这个生命周期
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)
......@@ -4,7 +4,7 @@
UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时,会涉及到启动特定的UIAbility,该UIAbility可以是应用内的其他UIAbility,也可以是其他应用的UIAbility(例如启动三方支付UIAbility)。
章节将从如下场景分别介绍设备内UIAbility间的交互方式。对于跨设备的应用组件交互,请参见[应用组件跨设备交互(流转)](inter-device-interaction-hop-overview.md)
将从如下场景分别介绍设备内UIAbility间的交互方式。对于跨设备的应用组件交互,请参见[应用组件跨设备交互(流转)](inter-device-interaction-hop-overview.md)
- [启动应用内的UIAbility](#启动应用内的uiability)
......@@ -15,6 +15,8 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
- [启动其他应用的UIAbility并获取返回结果](#启动其他应用的uiability并获取返回结果)
- [启动UIAbility指定窗口模式(仅对系统应用开放)](#启动uiability指定窗口模式仅对系统应用开放)
- [启动UIAbility的指定页面](#启动uiability的指定页面)
- [通过Call调用实现UIAbility交互(仅对系统应用开放)](#通过call调用实现uiability交互仅对系统应用开放)
......@@ -26,113 +28,134 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
假设应用中有两个UIAbility:EntryAbility和FuncAbility(可以在应用的一个Module中,也可以在的不同Module中),需要从EntryAbility的页面中启动FuncAbility。
1. 在EntryAbility中,通过调用startAbility()方法启动UIAbility,[want](../reference/apis/js-apis-app-ability-want.md)为UIAbility实例启动的入口参数,其中bundleName为待启动应用的Bundle名称,abilityName为待启动的UIAbility名称,moduleName在待启动的UIAbility属于不同的Module时添加,parameters为自定义信息参数。示例中的context的获取方式参见[获取UIAbility的Context属性](uiability-usage.md#获取uiability的上下文信息)
1. 在EntryAbility中,通过调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动UIAbility,[want](../reference/apis/js-apis-app-ability-want.md)为UIAbility实例启动的入口参数,其中bundleName为待启动应用的Bundle名称,abilityName为待启动的Ability名称,moduleName在待启动的UIAbility属于不同的Module时添加,parameters为自定义信息参数。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let wantInfo = {
let context = ...; // UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName非必选
moduleName: 'func', // moduleName非必选
parameters: { // 自定义信息
info: '来自EntryAbility Index页面',
},
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
// ...
// context为调用方UIAbility的UIAbilityContext
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}`);
})
```
2. 在FuncAbility的生命周期回调文件中接收EntryAbility传递过来的参数。
2. 在FuncAbility的[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)或者[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant)生命周期回调文件中接收EntryAbility传递过来的参数。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class FuncAbility extends UIAbility {
onCreate(want, launchParam) {
// 接收调用方UIAbility传过来的参数
let funcAbilityWant = want;
let info = funcAbilityWant?.parameters?.info;
// ...
...
}
}
```
3. 在FuncAbility业务完成之后,如需要停止当前UIAbility实例,在FuncAbility中通过调用terminateSelf()方法实现。
> **说明:**
>
> 在被拉起的FuncAbility中,可以通过获取传递过来的`want`参数的`parameters`来获取拉起方UIAbility的PID、Bundle Name等信息。
3. 在FuncAbility业务完成之后,如需要停止当前UIAbility实例,在FuncAbility中通过调用[`terminateSelf()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself)方法实现。
```ts
let context = ...; // UIAbilityContext
// context为需要停止的UIAbility实例的AbilityContext
this.context.terminateSelf((err) => {
// ...
context.terminateSelf((err) => {
if (err.code) {
console.error(`Failed to terminate Self. Code is ${err.code}, message is ${err.message}`);
return;
}
});
```
> **说明:**
>
> 调用[`terminateSelf()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself)方法停止当前UIAbility实例时,默认会保留该实例的快照(Snapshot),即在最近任务列表中仍然能查看到该实例对应的任务。如不需要保留该实例的快照,可以在其对应UIAbility的[module.json5配置文件](../quick-start/module-configuration-file.md)中,将[abilities标签](../quick-start/module-configuration-file.md#abilities标签)的removeMissionAfterTerminate字段配置为true。
4. 如需要关闭应用所有的UIAbility实例,可以调用[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md)`killProcessBySelf()`方法实现关闭应用所有的进程。
## 启动应用内的UIAbility并获取返回结果
在一个EntryAbility启动另外一个FuncAbility时,希望在被启动的FuncAbility完成相关业务后,能将结果返回给调用方。例如在应用中将入口功能和帐号登录功能分别设计为两个独立的UIAbility,在帐号登录UIAbility中完成登录操作后,需要将登录的结果返回给入口UIAbility。
1. 在EntryAbility中,调用startAbilityForResult()接口启动FuncAbility,异步回调中的data用于接收FuncAbility停止自身后返回给EntryAbility的信息。示例中的context的获取方式参见[获取UIAbility的Context属性](uiability-usage.md#获取uiability的上下文信息)
1. 在EntryAbility中,调用[`startAbilityForResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)接口启动FuncAbility,异步回调中的data用于接收FuncAbility停止自身后返回给EntryAbility的信息。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let wantInfo = {
let context = ...; // UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName非必选
moduleName: 'func', // moduleName非必选
parameters: { // 自定义信息
info: '来自EntryAbility Index页面',
},
}
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {
// ...
// context为调用方UIAbility的UIAbilityContext
context.startAbilityForResult(want).then((data) => {
...
}).catch((err) => {
// ...
console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);
})
```
2. 在FuncAbility停止自身时,需要调用terminateSelfWithResult()方法,入参abilityResult为FuncAbility需要返回给EntryAbility的信息。
2. 在FuncAbility停止自身时,需要调用[`terminateSelfWithResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)方法,入参abilityResult为FuncAbility需要返回给EntryAbility的信息。
```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001;
let abilityResult = {
resultCode: RESULT_CODE,
want: {
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1',
moduleName: 'func',
parameters: {
info: '来自FuncAbility Index页面',
},
},
}
// context为被调用方UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {
// ...
context.terminateSelfWithResult(abilityResult, (err) => {
if (err.code) {
console.error(`Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`);
return;
}
});
```
3. FuncAbility停止自身后,EntryAbility通过startAbilityForResult()方法回调接收被FuncAbility返回的信息,RESULT_CODE需要与前面的数值保持一致。
3. FuncAbility停止自身后,EntryAbility通过[`startAbilityForResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)方法回调接收被FuncAbility返回的信息,RESULT_CODE需要与前面的数值保持一致。
```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001;
// ...
...
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {
// context为调用方UIAbility的UIAbilityContext
context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) {
// 解析被调用方UIAbility返回的信息
let info = data.want?.parameters?.info;
// ...
...
}
}).catch((err) => {
// ...
console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);
})
```
......@@ -145,26 +168,26 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
- 显式Want启动:启动一个确定应用的UIAbility,在want参数中需要设置该应用bundleName和abilityName,当需要拉起某个明确的UIAbility时,通常使用显式Want启动方式。
- 隐式Want启动:根据匹配条件由用户选择启动哪一个UIAbility,即不明确指出要启动哪一个UIAbility(abilityName参数未设置),在调用startAbility()方法时,其入参want中指定了一系列的[entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity)字段(表示目标UIAbility额外的类别信息,如浏览器、视频播放器)和[actions](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction)字段(表示要执行的通用操作,如查看、分享、应用详情等)等参数信息,然后由系统去分析want,并帮助找到合适的UIAbility来启动。当需要拉起其他应用的UIAbility时,开发者通常不知道用户设备中应用的安装情况,也无法确定目标应用的bundleName和abilityName,通常使用隐式Want启动方式。
- 隐式Want启动:根据匹配条件由用户选择启动哪一个UIAbility,即不明确指出要启动哪一个UIAbility(abilityName参数未设置),在调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,其入参want中指定了一系列的entities字段(表示目标UIAbility额外的类别信息,如浏览器、视频播放器)和actions字段(表示要执行的通用操作,如查看、分享、应用详情等)等参数信息,然后由系统去分析want,并帮助找到合适的UIAbility来启动。当需要拉起其他应用的UIAbility时,开发者通常不知道用户设备中应用的安装情况,也无法确定目标应用的bundleName和abilityName,通常使用隐式Want启动方式。
章节主要讲解如何通过隐式Want启动其他应用的UIAbility。
主要讲解如何通过隐式Want启动其他应用的UIAbility。
1. 将多个待匹配的文档应用安装到设备,在其对应UIAbility的module.json5配置文件中,配置skills的[entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity)字段和[actions](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction)字段。
1. 将多个待匹配的文档应用安装到设备,在其对应UIAbility的[module.json5配置文件](../quick-start/module-configuration-file.md)中,配置skills标签的entities字段和actions字段。
```json
{
"module": {
"abilities": [
{
// ...
...
"skills": [
{
"entities": [
// ...
...
"entity.system.default"
],
"actions": [
// ...
...
"ohos.want.action.viewData"
]
}
......@@ -175,10 +198,11 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
}
```
2. 在调用方want参数中的entities和action需要被包含在待匹配UIAbility的skills配置的entities和actions中。系统匹配到符合entities和actions参数条件的UIAbility后,会弹出选择框展示匹配到的UIAbility实例列表供用户选择使用。示例中的context的获取方式参见[获取UIAbility的Context属性](uiability-usage.md#获取uiability的上下文信息)
2. 在调用方want参数中的entities和action需要被包含在待匹配UIAbility的skills配置的entities和actions中。系统匹配到符合entities和actions参数条件的UIAbility后,会弹出选择框展示匹配到的UIAbility实例列表供用户选择使用。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let wantInfo = {
let context = ...; // UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
......@@ -187,48 +211,52 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
entities: ['entity.system.default'],
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
// ...
// context为调用方UIAbility的UIAbilityContext
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}`);
})
```
效果示意如下图所示,点击“打开PDF文档”时,会弹出选择框供用户选择。
![](figures/uiability-intra-device-interaction.png)
![uiability-intra-device-interaction](figures/uiability-intra-device-interaction.png)
3. 在文档应用使用完成之后,如需要停止当前UIAbility实例,通过调用terminateSelf()方法实现。
3. 在文档应用使用完成之后,如需要停止当前UIAbility实例,通过调用[`terminateSelf()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself)方法实现。
```ts
let context = ...; // UIAbilityContext
// context为需要停止的UIAbility实例的AbilityContext
this.context.terminateSelf((err) => {
// ...
context.terminateSelf((err) => {
if (err.code) {
console.error(`Failed to terminate self. Code is ${err.code}, message is ${err.message}`);
return;
}
});
```
## 启动其他应用的UIAbility并获取返回结果
当使用隐式Want启动其他应用的UIAbility并希望获取返回结果时,调用方需要使用startAbilityForResult()方法启动目标UIAbility。例如主应用中需要启动三方支付并获取支付结果。
当使用隐式Want启动其他应用的UIAbility并希望获取返回结果时,调用方需要使用[`startAbilityForResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)方法启动目标UIAbility。例如主应用中需要启动三方支付并获取支付结果。
1. 在支付应用对应UIAbility的module.json5配置文件中,配置skills的[entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity)字段和[actions](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction)字段。
1. 在支付应用对应UIAbility的[module.json5配置文件](../quick-start/module-configuration-file.md)中,配置skills的entities字段和actions字段。
```json
{
"module": {
"abilities": [
{
// ...
...
"skills": [
{
"entities": [
// ...
...
"entity.system.default"
],
"actions": [
// ...
...
"ohos.want.action.editData"
]
}
......@@ -239,29 +267,31 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
}
```
2. 调用方使用startAbilityForResult()方法启动支付应用的UIAbility,在调用方want参数中的entities和action需要被包含在待匹配UIAbility的skills配置的entities和actions中。异步回调中的data用于后续接收支付UIAbility停止自身后返回给调用方的信息。系统匹配到符合entities和actions参数条件的UIAbility后,会弹出选择框展示匹配到的UIAbility实例列表供用户选择使用。
2. 调用方使用[`startAbilityForResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)方法启动支付应用的UIAbility,在调用方want参数中的entities和action需要被包含在待匹配UIAbility的skills标签配置的entities和actions中。异步回调中的data用于后续接收支付UIAbility停止自身后返回给调用方的信息。系统匹配到符合entities和actions参数条件的UIAbility后,会弹出选择框展示匹配到的UIAbility实例列表供用户选择使用。
```ts
let wantInfo = {
let context = ...; // UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.editData',
// entities can be omitted.
entities: ['entity.system.default'],
entities: ['entity.system.default']
}
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {
// ...
// context为调用方UIAbility的UIAbilityContext
context.startAbilityForResult(want).then((data) => {
...
}).catch((err) => {
// ...
console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);
})
```
3. 在支付UIAbility完成支付之后,需要调用terminateSelfWithResult()方法实现停止自身,并将abilityResult参数信息返回给调用方。
3. 在支付UIAbility完成支付之后,需要调用[`terminateSelfWithResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)方法实现停止自身,并将abilityResult参数信息返回给调用方。
```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001;
let abilityResult = {
resultCode: RESULT_CODE,
......@@ -275,32 +305,86 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
},
}
// context为被调用方UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {
// ...
context.terminateSelfWithResult(abilityResult, (err) => {
if (err.code) {
console.error(`Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`);
return;
}
});
```
4. 在调用方startAbilityForResult()方法回调中接收支付应用返回的信息,RESULT_CODE需要与前面terminateSelfWithResult()返回的数值保持一致。
4. 在调用方[`startAbilityForResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)方法回调中接收支付应用返回的信息,RESULT_CODE需要与前面[`terminateSelfWithResult()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult)返回的数值保持一致。
```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001;
let want = {
// Want参数信息
};
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {
// context为调用方UIAbility的UIAbilityContext
context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) {
// 解析被调用方UIAbility返回的信息
let payResult = data.want?.parameters?.payResult;
// ...
...
}
}).catch((err) => {
// ...
console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);
})
```
## 启动UIAbility指定窗口模式(仅对系统应用开放)
当用户打开应用时,应用程序会以不同的窗口模式进行展示,即启动UIAbility的窗口模式。应用程序可以启动为全屏模式,悬浮窗模式或分屏模式。
全屏模式是指应用程序启动后,占据整个屏幕,用户无法同时查看其他窗口或应用程序。全屏模式通常适用于那些要求用户专注于特定任务或界面的应用程序。
悬浮窗模式是指应用程序启动后,以浮动窗口的形式显示在屏幕上,用户可以轻松切换到其他窗口或应用程序。悬浮窗通常适用于需要用户同时处理多个任务的应用程序。
分屏模式允许用户在同一屏幕上同时运行两个应用程序,其中一个应用程序占据屏幕左侧/上侧的一部分,另一个应用程序占据右侧/下侧的一部分。分屏模式主要用于提高用户的多任务处理效率。
使用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动UIAbility时,可以通过在入参中增加[StartOptions](../reference/apis/js-apis-app-ability-startOptions.md)参数的windowMode属性来配置启动UIAbility的窗口模式。
> **说明:**
>
> 1. 如果在使用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动UIAbility时,入参中未指定[StartOptions](../reference/apis/js-apis-app-ability-startOptions.md)参数的windowMode属性,那么UIAbility将以系统默认的窗口展示形态启动。
> 2. 为了确保启动的UIAbility展示形态能够被支持,需要在该UIAbility对应的[module.json5配置文件](../quick-start/module-configuration-file.md)中[abilities标签](../quick-start/module-configuration-file.md#abilities标签)的supportWindowMode字段确认启动的展示形态被支持。
以下是具体的操作步骤,以悬浮窗模式为例,假设需要从EntryAbility的页面中启动FuncAbility:
1. 在调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,增加[StartOptions](../reference/apis/js-apis-app-ability-startOptions.md)参数。
2.[StartOptions](../reference/apis/js-apis-app-ability-startOptions.md)参数中设置`windowMode`字段为`WINDOW_MODE_FLOATING`,表示启动的UIAbility将以悬浮窗的形式展示。
示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
let context = ...; // UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'func', // moduleName非必选
parameters: { // 自定义信息
info: '来自EntryAbility Index页面',
},
}
let options = {
windowMode: AbilityConstant.WindowMode.WINDOW_MODE_FLOATING
};
// context为调用方UIAbility的UIAbilityContext
context.startAbility(want, options).then(() => {
console.info('Succeeded in starting ability.');
}).catch((err) => {
console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`);
})
```
效果示意如下图所示。
![](figures/start-uiability-floating-window.png)
## 启动UIAbility的指定页面
......@@ -309,31 +393,32 @@ UIAbility是系统调度的最小单元。在设备内的功能模块之间跳
### 调用方UIAbility指定启动页面
调用方UIAbility启动另外一个UIAbility时,通常需要跳转到指定的页面。例如FuncAbility包含两个页面(Index对应首页,Second对应功能A页面),此时需要在传入的want参数中配置指定的页面路径信息,可以通过want中的parameters参数增加一个自定义参数传递页面跳转信息。示例中的context的获取方式参见[获取UIAbility的Context属性](uiability-usage.md#获取uiability的上下文信息)
调用方UIAbility启动另外一个UIAbility时,通常需要跳转到指定的页面。例如FuncAbility包含两个页面(Index对应首页,Second对应功能A页面),此时需要在传入的want参数中配置指定的页面路径信息,可以通过want中的parameters参数增加一个自定义参数传递页面跳转信息。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let wantInfo = {
let context = ...; // UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName非必选
moduleName: 'func', // moduleName非必选
parameters: { // 自定义参数传递页面信息
router: 'funcA',
},
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
// ...
// context为调用方UIAbility的UIAbilityContext
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}`);
})
```
### 目标UIAbility首次启动
目标UIAbility首次启动时,在目标UIAbility的onWindowStageCreate()生命周期回调中,解析EntryAbility传递过来的want参数,获取到需要加载的页面信息url,传入windowStage.loadContent()方法。
目标UIAbility首次启动时,在目标UIAbility的`onWindowStageCreate()`生命周期回调中,解析EntryAbility传递过来的want参数,获取到需要加载的页面信息url,传入`windowStage.loadContent()`方法。
```ts
......@@ -357,7 +442,7 @@ export default class FuncAbility extends UIAbility {
}
}
windowStage.loadContent(url, (err, data) => {
// ...
...
});
}
}
......@@ -372,7 +457,7 @@ export default class FuncAbility extends UIAbility {
针对以上场景,即当应用A的UIAbility实例已创建,并且处于该UIAbility实例对应的主页面中,此时,从应用B中需要再次启动应用A的该UIAbility,并且需要跳转到不同的页面,这种情况下要如何实现呢?
1. 在目标UIAbility中,默认加载的是Index页面。由于当前UIAbility实例之前已经创建完成,此时会进入UIAbility的onNewWant()回调中且不会进入onCreate()和onWindowStageCreate()生命周期回调,在onNewWant()回调中解析调用方传递过来的want参数,并挂在到全局变量globalThis中,以便于后续在页面中获取。
1. 在目标UIAbility中,默认加载的是Index页面。由于当前UIAbility实例之前已经创建完成,此时会进入UIAbility的`onNewWant()`回调中且不会进入`onCreate()``onWindowStageCreate()`生命周期回调,在onNewWant()回调中解析调用方传递过来的want参数,并挂在到全局变量globalThis中,以便于后续在页面中获取。
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
......@@ -381,12 +466,12 @@ export default class FuncAbility extends UIAbility {
onNewWant(want, launchParam) {
// 接收调用方UIAbility传过来的参数
globalThis.funcAbilityWant = want;
// ...
...
}
}
```
2. 在FuncAbility中,此时需要在Index页面中通过页面路由Router模块实现指定页面的跳转,由于此时FuncAbility对应的Index页面是处于激活状态,不会重新变量声明以及进入aboutToAppear()生命周期回调中。因此可以在Index页面的onPageShow()生命周期回调中实现页面路由跳转的功能。
2. 在FuncAbility中,此时需要在Index页面中通过页面路由Router模块实现指定页面的跳转,由于此时FuncAbility对应的Index页面是处于激活状态,不会重新变量声明以及进入`aboutToAppear()`生命周期回调中。因此可以在Index页面的`onPageShow()`生命周期回调中实现页面路由跳转的功能。
```ts
import router from '@ohos.router';
......@@ -406,24 +491,24 @@ export default class FuncAbility extends UIAbility {
// 页面展示
build() {
// ...
...
}
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 当被调用方[Ability的启动模式](uiability-launch-type.md)设置为standard启动模式时,每次启动都会创建一个新的实例,那么[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调就不会被用到。
> **说明:**
> 当被调用方[UIAbility组件启动模式](uiability-launch-type.md)设置为multiton启动模式时,每次启动都会创建一个新的实例,那么[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调就不会被用到。
## 通过Call调用实现UIAbility交互(仅对系统应用开放)
Call调用是UIAbility能力的扩展,它为UIAbility提供一种能够被外部调用并与外部进行通信的能力。Call调用支持前台与后台两种启动方式,使UIAbility既能被拉起到前台展示UI,也可以在后台被创建并运行。Call调用在调用方与被调用方间建立了IPC通信,因此应用开发者可通过Call调用实现不同Ability之间的数据共享。
Call调用是UIAbility能力的扩展,它为UIAbility提供一种能够被外部调用并与外部进行通信的能力。Call调用支持前台与后台两种启动方式,使UIAbility既能被拉起到前台展示UI,也可以在后台被创建并运行。Call调用在调用方与被调用方间建立了IPC通信,因此应用开发者可通过Call调用实现不同UIAbility之间的数据共享。
Call调用的核心接口是startAbilityByCall方法,与startAbility接口的不同之处在于:
Call调用的核心接口是`startAbilityByCall()`方法,与`startAbility()`接口的不同之处在于:
- startAbilityByCall支持前台与后台两种启动方式,而startAbility仅支持前台启动。
- startAbilityByCall支持前台与后台两种启动方式,而`startAbility()`仅支持前台启动。
- 调用方可使用startAbilityByCall所返回的Caller对象与被调用方进行通信,而startAbilty不具备通信能力。
- 调用方可使用`startAbilityByCall()`所返回的Caller对象与被调用方进行通信,而`startAbilty()`不具备通信能力。
Call调用的使用场景主要包括:
......@@ -431,7 +516,8 @@ Call调用的使用场景主要包括:
- 希望被启动的UIAbility在后台运行。
**表1** Call调用相关名词解释
**表1** Call调用相关名词解释
| 名词 | 描述 |
| -------- | -------- |
......@@ -442,15 +528,14 @@ Call调用的使用场景主要包括:
Call调用示意图如下所示。
**图1** Call调用示意图
![call](figures/call.png)
**图1** Call调用示意图
![call](figures/call.png)
- CallerAbility调用startAbilityByCall接口获取Caller,并使用Caller对象的call方法向CalleeAbility发送数据。
- CalleeAbility持有一个Callee对象,通过Callee的on方法注册回调函数,当接收到Caller发送的数据时将会调用对应的回调函数。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 1. 当前仅支持系统应用使用Call调用。
>
> 2. CalleeAbility的启动模式需要为单实例。
......@@ -462,7 +547,7 @@ Call调用示意图如下所示。
Call功能主要接口如下表所示。具体的API详见[接口文档](../reference/apis/js-apis-app-ability-uiAbility.md#caller)
**表2** Call功能主要接口
**表2** Call功能主要接口
| 接口名 | 描述 |
| -------- | -------- |
......@@ -485,32 +570,14 @@ Call功能主要接口如下表所示。具体的API详见[接口文档](../refe
在Callee被调用端,需要实现指定方法的数据接收回调函数、数据的序列化及反序列化方法。在需要接收数据期间,通过on接口注册监听,无需接收数据时通过off接口解除监听。
1. 配置Ability的启动模式。
配置module.json5,将CalleeAbility配置为单实例"singleton"。
| Json字段 | 字段说明 |
| -------- | -------- |
| "launchType" | Ability的启动模式,设置为"singleton"类型。 |
1. 配置UIAbility的启动模式。
Ability配置标签示例如下:
```json
"abilities":[{
"name": ".CalleeAbility",
"srcEnty": "./ets/CalleeAbility/CalleeAbility.ts",
"launchType": "singleton",
"description": "$string:CalleeAbility_desc",
"icon": "$media:icon",
"label": "$string:CalleeAbility_label",
"exported": true
}]
```
例如将CalleeAbility配置为单实例模式`singleton`,配置方式请参见[UIAbility组件启动模式](uiability-launch-type.md)
2. 导入UIAbility模块。
```ts
import Ability from '@ohos.app.ability.UIAbility';
import UIAbility from '@ohos.app.ability.UIAbility';
```
3. 定义约定的序列化数据。
......@@ -519,30 +586,31 @@ Call功能主要接口如下表所示。具体的API详见[接口文档](../refe
```ts
export default class MyParcelable {
num: number = 0
str: string = ""
num: number = 0;
str: string = '';
constructor(num, string) {
this.num = num
this.str = string
this.num = num;
this.str = string;
}
marshalling(messageSequence) {
messageSequence.writeInt(this.num)
messageSequence.writeString(this.str)
return true
messageSequence.writeInt(this.num);
messageSequence.writeString(this.str);
return true;
}
unmarshalling(messageSequence) {
this.num = messageSequence.readInt()
this.str = messageSequence.readString()
return true
this.num = messageSequence.readInt();
this.str = messageSequence.readString();
return true;
}
}
```
4. 实现Callee.on监听及Callee.off解除监听。
被调用端Callee的监听函数注册时机,取决于应用开发者。注册监听之前的数据不会被处理,取消监听之后的数据不会被处理。如下示例在Ability的onCreate注册'MSG_SEND_METHOD'监听,在onDestroy取消监听,收到序列化数据后作相应处理并返回,应用开发者根据实际需要做相应处理。具体示例代码如下:
被调用端Callee的监听函数注册时机,取决于应用开发者。注册监听之前的数据不会被处理,取消监听之后的数据不会被处理。如下示例在UIAbility的onCreate注册'MSG_SEND_METHOD'监听,在onDestroy取消监听,收到序列化数据后作相应处理并返回,应用开发者根据实际需要做相应处理。具体示例代码如下:
```ts
......@@ -562,20 +630,20 @@ Call功能主要接口如下表所示。具体的API详见[接口文档](../refe
return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`);
}
export default class CalleeAbility extends Ability {
export default class CalleeAbility extends UIAbility {
onCreate(want, launchParam) {
try {
this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
} catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
} catch (err) {
console.error(`Failed to register. Code is ${err.code}, message is ${err.message}`);
}
}
onDestroy() {
try {
this.callee.off(MSG_SEND_METHOD);
} catch (error) {
console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
} catch (err) {
console.error(`Failed to unregister. Code is ${err.code}, message is ${err.message}`);
}
}
}
......@@ -587,23 +655,23 @@ Call功能主要接口如下表所示。具体的API详见[接口文档](../refe
1. 导入UIAbility模块。
```ts
import Ability from '@ohos.app.ability.UIAbility';
import UIAbility from '@ohos.app.ability.UIAbility';
```
2. 获取Caller通信接口。
Ability的context属性实现了startAbilityByCall方法,用于获取指定通用组件的Caller通信接口。如下示例通过this.context获取Ability实例的context属性,使用startAbilityByCall拉起Callee被调用端并获取Caller通信接口,注册Caller的onRelease监听。应用开发者根据实际需要做相应处理。
UIAbilityContext属性实现了startAbilityByCall方法,用于获取指定通用组件的Caller通信接口。如下示例通过this.context获取UIAbility实例的context属性,使用startAbilityByCall拉起Callee被调用端并获取Caller通信接口,注册Caller的onRelease监听。应用开发者根据实际需要做相应处理。
```ts
// 注册caller的release监听
private regOnRelease(caller) {
try {
caller.on("release", (msg) => {
caller.on('release', (msg) => {
console.info(`caller onRelease is called ${msg}`);
})
console.info('caller register OnRelease succeed');
} catch (error) {
console.info(`caller register OnRelease failed with ${error}`);
console.info('Succeeded in registering on release.');
} catch (err) {
console.err(`Failed to caller register on release. Code is ${err.code}, message is ${err.message}`);
}
}
......@@ -612,15 +680,15 @@ Call功能主要接口如下表所示。具体的API详见[接口文档](../refe
this.caller = await context.startAbilityByCall({
bundleName: 'com.samples.CallApplication',
abilityName: 'CalleeAbility'
})
});
if (this.caller === undefined) {
console.info('get caller failed')
return
return;
}
console.info('get caller success')
this.regOnRelease(this.caller)
} catch (error) {
console.info(`get caller failed with ${error}`)
} (err) {
console.err(`Failed to get caller. Code is ${err.code}, message is ${err.message}`);
}
}
```
......@@ -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,46 +79,47 @@ 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非必选
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';
......@@ -139,7 +140,7 @@ specified启动模式为指定实例模式,针对一些特殊场景使用(
> **说明:**
>
> 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,63 +16,101 @@ 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) {
// 应用初始化
}
// ...
...
}
```
> **说明**:[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) {
...
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界面加载
// 设置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 {
// ...
windowStage: window.WindowStage;
...
onWindowStageCreate(windowStage: window.WindowStage) {
this.windowStage = windowStage;
...
}
onWindowStageDestroy() {
// 释放UI界面资源
// 释放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}`);
};
}
}
```
......@@ -81,27 +118,29 @@ export default class EntryAbility extends UIAbility {
### 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()中释放的资源
}
onBackground() {
// 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
}
......@@ -112,13 +151,14 @@ 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() {
// 系统资源的释放、数据的保存等
}
......
......@@ -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,34 +6,34 @@ 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) {
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';
......@@ -42,8 +42,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
onCreate(want, launchParam) {
// 获取UIAbility实例的上下文
let context = this.context;
// ...
...
}
}
```
......@@ -67,7 +66,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
// 页面展示
build() {
// ...
...
}
}
```
......@@ -92,7 +91,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
// 页面展示
build() {
// ...
...
}
}
```
......@@ -3,16 +3,19 @@
## 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 = {
......@@ -22,8 +25,9 @@
}
```
- **隐式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
......@@ -38,27 +42,12 @@
};
```
> ![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)所示。 |
......@@ -49,7 +49,7 @@
- 通信适配层:由OpenHarmony SDK提供,负责与卡片管理服务通信,用于将卡片的更新数据主动推送到卡片管理服务。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> 实际开发时只需要作为卡片提供方进行卡片内容的开发,卡片使用方和卡片管理服务由系统自动处理。
......@@ -166,7 +166,7 @@ FA卡片开发,即基于[FA模型](fa-model-development-overview.md)的卡片
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> FormAbility不能常驻后台,即在卡片生命周期回调函数中无法处理长时间的任务。
### 配置卡片配置文件
......@@ -230,7 +230,7 @@ FA卡片开发,即基于[FA模型](fa-model-development-overview.md)的卡片
"type": "service",
"srcLanguage": "ets",
"formsEnabled": true,
"formConfigAbility": "ability://com.example.entry.MainAbility",
"formConfigAbility": "ability://com.example.entry.EntryAbility",
"forms": [{
"colorMode": "auto",
"defaultDimension": "2*2",
......@@ -273,7 +273,7 @@ async function storeFormInfo(formId: string, formName: string, tempFlag: boolean
}
}
// ...
...
onCreate(want) {
console.info('FormAbility onCreate');
......@@ -291,7 +291,7 @@ async function storeFormInfo(formId: string, formName: string, tempFlag: boolean
let formData = formBindingData.createFormBindingData(obj);
return formData;
}
// ...
...
```
且需要适配onDestroy卡片删除通知接口,在其中实现卡片实例数据的删除。
......@@ -311,14 +311,14 @@ async function deleteFormInfo(formId: string) {
}
}
// ...
...
onDestroy(formId) {
console.info('FormAbility onDestroy');
// 删除之前持久化的卡片实例数据
// 此接口请根据实际情况实现,具体请参考:FormExtAbility Stage模型卡片实例
deleteFormInfo(formId);
}
// ...
...
```
具体的持久化方法可以参考[数据管理开发指导](../database/app-data-persistence-overview.md)
......@@ -360,8 +360,8 @@ onUpdate(formId) {
![widget-development-fa](figures/widget-development-fa.png)
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> FA模型当前仅支持JS扩展的类Web开发范式来实现卡片的UI界面
> **说明:**
> FA模型当前仅支持JS扩展的类Web开发范式来实现卡片的UI。
- HML:使用类Web范式的组件描述卡片的页面信息。
......@@ -431,7 +431,7 @@ onUpdate(formId) {
"actions": {
"routerEvent": {
"action": "router",
"abilityName": "com.example.entry.MainAbility",
"abilityName": "com.example.entry.EntryAbility",
"params": {
"message": "add detail"
}
......@@ -449,8 +449,8 @@ onUpdate(formId) {
2. 如何设置router事件:
- action属性值为"router";
- abilityName为跳转目标的Ability名(支持跳转FA模型的PageAbility组件和Stage模型的UIAbility组件),如目前DevEco创建的FA模型的MainAbility默认名为com.example.entry.MainAbility;
- params为传递给跳转目标Ability的自定义参数,可以按需填写。其值可以在目标Ability启动时的want中的parameters里获取。如FA模型MainAbility的onCreate生命周期里可以通过featureAbility.getWant()获取到want,然后在其parameters字段下获取到配置的参数;
- abilityName为跳转目标的Ability名(支持跳转FA模型的PageAbility组件和Stage模型的UIAbility组件),如目前DevEco创建的FA模型的UIAbility默认名为com.example.entry.EntryAbility;
- params为传递给跳转目标Ability的自定义参数,可以按需填写。其值可以在目标Ability启动时的want中的parameters里获取。如FA模型EntryAbility的onCreate生命周期里可以通过featureAbility.getWant()获取到want,然后在其parameters字段下获取到配置的参数;
3. 如何设置message事件:
- action属性值为"message";
......@@ -526,7 +526,7 @@ onUpdate(formId) {
"actions": {
"routerEvent": {
"action": "router",
"abilityName": "com.example.entry.MainAbility",
"abilityName": "com.example.entry.EntryAbility",
"params": {
"message": "add detail"
}
......@@ -540,13 +540,3 @@ onUpdate(formId) {
}
}
```
## 相关实例
针对FA模型卡片提供方的开发,有以下相关实例可供参考:
- [FormAbility:FA模型卡片(ArkTS)(API8)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/ability/FormAbility)
- [FormLauncher:卡片使用方(ArkTS)(API8)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/ability/FormLauncher)
......@@ -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 |
......
......@@ -6,7 +6,6 @@
WindowExtensionAbility必须和[AbilityComponent](../reference/arkui-ts/ts-container-ability-component.md)一起配合使用,并根据需求处理被拉起应用的业务。WindowExtensionAbility支持以连接形式运行,系统应用必须添加AbilityComponent组件启动WindowExtensionAbility服务。
每个ExtensionAbility都有自己的Context,WindowExtensionAbility通过
[WindowExtensionContext](../reference/apis/js-apis-inner-application-windowExtensionContext.md)提供相关能力。本文描述中称被启动的WindowExtensionAbility为提供方,称启动WindowExtensionAbility的AbilityComponent组件为使用方。
......@@ -16,7 +15,7 @@ WindowExtensionAbility必须和[AbilityComponent](../reference/arkui-ts/ts-conta
>
## 设置一个嵌入式Ability(仅对系统应用开放)
## 设置一个嵌入式UIAbility(仅对系统应用开放)
WindowExtensionAbility提供了onConnect()、onDisconnect()和onWindowReady()生命周期回调,根据需要重写对应的回调方法。
......@@ -44,7 +43,7 @@ WindowExtensionAbility提供了onConnect()、onDisconnect()和onWindowReady()生
onWindowReady(window) {
window.loadContent('WindowExtAbility/pages/index1').then(() => {
window.getProperties().then((pro) => {
console.log("WindowExtension " + JSON.stringify(pro));
console.info("WindowExtension " + JSON.stringify(pro));
})
window.show();
})
......@@ -60,7 +59,7 @@ WindowExtensionAbility提供了onConnect()、onDisconnect()和onWindowReady()生
}
```
4. 在工程Module对应的[module.json5配置文件](../quick-start/module-configuration-file.md)中注册WindowExtensionAbility,type标签需要设置为“window”,srcEnty标签表示当前ExtensionAbility组件所对应的代码路径。
4. 在工程Module对应的[module.json5配置文件](../quick-start/module-configuration-file.md)中注册WindowExtensionAbility,type标签需要设置为“window”,srcEntry标签表示当前ExtensionAbility组件所对应的代码路径。
```json
{
......@@ -68,7 +67,7 @@ WindowExtensionAbility提供了onConnect()、onDisconnect()和onWindowReady()生
"extensionAbilities": [
{
"name": "WindowExtAbility",
"srcEnty": "./ets/WindowExtAbility/WindowExtAbility.ts",
"srcEntry": "./ets/WindowExtAbility/WindowExtAbility.ts",
"icon": "$media:icon",
"description": "WindowExtension",
"type": "window",
......@@ -80,7 +79,7 @@ WindowExtensionAbility提供了onConnect()、onDisconnect()和onWindowReady()生
```
## 拉起一个嵌入式Ability(仅对系统应用开放)
## 拉起一个嵌入式UIAbility(仅对系统应用开放)
系统应用可以通过AbilityComponent容器加载创建好的WindowExtensionAbility。
......@@ -113,8 +112,8 @@ struct Index {
}
```
## 相关
## 相关
针对WindowExtensionAbility开发,有以下相关例可供参考:
针对WindowExtensionAbility开发,有以下相关例可供参考:
- [`WindowExtAbility`:WindowExtAbility的创建与使用(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/ability/WindowExtAbility)
- [`WindowExtAbility`:WindowExtAbility的创建与使用(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/WindowManagement/WindowExtAbility)
......@@ -13,11 +13,11 @@
## 配置文件权限声明
应用需要在工程配置文件中,对需要的权限逐个声明,未在配置文件中声明的权限,应用将无法获得授权。OpenHarmony提供了两种应用模型,分别为FA模型和Stage模型,更多信息可以参考[应用模型解读](../application-models/application-model-description.md)。不同的应用模型的应用包结构不同,所使用的配置文件不同
应用需要在项目的配置文件中逐个声明所需的权限,否则应用将无法获取授权
> **说明**:
>
> 应用默认的APL等级为`normal`,当应用需要申请`system_basic`和`system_core`等级时,除了在配置文件中进行权限声明之外,还需要通过[ACL方式](#acl方式声明)进行声明使用。
> 应用在申请`system_basic`和`system_core`等级权限时,需要提升权限等级,因为应用默认的权限等级为`normal`。如果应用需要申请高于默认等级的权限,除了在配置文件中进行声明之外,还需要通过[ACL方式](#acl方式声明)进行声明使用。
配置文件标签说明如下表所示。
......@@ -100,9 +100,9 @@
## ACL方式声明
应用在申请`system_basic``system_core`等级权限时,高于应用默认的`normal`等级。当应用需要申请权限项的等级高于应用默认的等级时,需要通过ACL方式进行声明使用。
当应用需要申请`system_basic``system_core`等级的权限时,比应用默认权限等级`normal`更高。如果需要申请的权限等级高于应用默认的等级,需要使用ACL方式声明使用。
例如应用在申请访问用户公共目录下音乐类型的文件,需要申请` ohos.permission.WRITE_AUDIO`权限,该权限为`system_basic`等级;以及应用在申请截取屏幕图像功能,该权限为`system_core`等级,需要申请` ohos.permission.CAPTURE_SCREEN`权限。此时需要将相关权限项配置到[HarmonyAppProvision配置文件](app-provision-structure.md)`acl`字段中。
例如,如果应用需要访问用户公共目录中的音乐文件,需要申请`ohos.permission.WRITE_AUDIO`权限,该权限属于`system_basic`等级。如果应用需要截取屏幕图像,则需要申请`ohos.permission.CAPTURE_SCREEN`权限,该权限属于`system_core`等级。此时,需要将相关权限项配置到[HarmonyAppProvision配置文件](app-provision-structure.md)`acl`字段中。
```json
{
......@@ -131,7 +131,7 @@
以允许应用读取日历信息为例进行说明。
1. 申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[访问控制授权申请](#配置文件权限声明)
1. 申请`ohos.permission.READ_CALENDAR`权限,配置方式请参见[配置文件权限声明](#配置文件权限声明)
2. 校验当前是否已经授权。
......@@ -152,14 +152,14 @@
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (err) {
console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);
console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
}
// 校验应用是否被授予权限
try {
grantStatus = await atManager.checkAccessToken(tokenId, permission);
} catch (err) {
console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`);
console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
}
return grantStatus;
......@@ -214,8 +214,7 @@
}
// 授权成功
}).catch((err) => {
console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
})
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
// ...
}
......@@ -249,7 +248,7 @@
}
// 授权成功
}).catch((err) => {
console.error(`requestPermissionsFromUser failed, code is ${err.code}, message is ${err.message}`);
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册