“70e71227852cb70d6aa7e4d44afd506ed362ba83”上不存在“paddle/fluid/git@gitcode.net:s920243400/PaddleDetection.git”
提交 a749b52e 编写于 作者: zyjhandsome's avatar zyjhandsome

优化代码格式、优化部分描述,应用模型基本概念中,优化对应的图示

Signed-off-by: zyjhandsome's avatarzyjhandsome <zyjhandsome@126.com>
上级 dfbeea19
......@@ -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)
......
# 使用显式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匹配成功。
当存在多个匹配的应用时,系统将弹出应用选择框供用户选择。示意效果如下图所示。
![](figures/ability-startup-with-implicit-want1.png)
......@@ -37,7 +37,7 @@ DevEco Studio默认工程中未自动生成AbilityStage,如需要使用Ability
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",
// ...
...
}
}
```
......
# 常见action与entities
**action**:表示调用方要执行的通用操作(如查看、分享、应用详情)。在隐式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**
......@@ -14,10 +13,9 @@
- ACTION_VIEW_MULTIPLE_DATA:发送多个数据记录的操作。
**entities**:表示目标Ability的类别信息(如浏览器、视频播放器),在隐式Want中是对action的补充。在隐式Want中,开发者可定义该字段,来过滤匹配应用的类别,例如必须是浏览器。在Want内声明entities字段表示希望被调用方应用属于声明的类别。在被调用方应用配置文件skills字段内声明entites表示该应用支持的类别。
**entities**:表示目标应用组件的类别信息(如浏览器、视频播放器),在隐式Want中是对action的补充。在隐式Want中,开发者可定义该字段,来过滤匹配应用的类别,例如必须是浏览器。在Want内声明entities字段表示希望被调用方应用属于声明的类别。在被调用方应用配置文件skills字段内声明entites表示该应用支持的类别。
**常entities**
**常entities**
- ENTITY_DEFAULT:默认类别无实际意义。
......
......@@ -24,7 +24,7 @@ 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模型不支持 |
......
......@@ -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)
- **应用包名配置**
......@@ -22,13 +23,13 @@
应用标签需要在工程的AppScope模块下的[app.json5配置文件](../quick-start/app-configuration-file.md)中配置label标签。标识应用对用户显示的名称,需要配置为字符串资源的索引。
```json
{
"app": {
"icon": "$media:app_icon",
"label": "$string:app_name"
// ...
}
{
"app": {
"icon": "$media:app_icon",
"label": "$string:app_name"
...
}
}
```
- **入口图标和标签配置**
......@@ -40,7 +41,7 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// $开头的为资源值
......
......@@ -5,14 +5,12 @@
[Context](../reference/apis/js-apis-inner-application-context.md)是应用中对象的上下文,其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用开发路径)、area(文件分区)等,以及应用的一些基本方法,例如createBundleContext()、getApplicationContext()等。UIAbility组件和各种ExtensionAbility派生类组件都有各自不同的Context类。分别有基类Context、ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionContext、ServiceExtensionContext等Context。
- 各类Context的继承关系
- 各类Context的继承关系
![context-inheritance](figures/context-inheritance.png)
- 各类Context的持有关系
- 各类Context的持有关系
![context-holding](figures/context-holding.png)
- 各类Context的获取方式
- 获取[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)。每个UIAbility中都包含了一个Context属性,提供操作应用组件、获取应用组件的配置信息等能力。
......@@ -21,7 +19,7 @@
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let uiAbilityContext = this.context;
// ...
...
}
}
```
......@@ -36,7 +34,7 @@
export default class MyService extends ServiceExtensionAbility {
onCreate(want) {
let serviceExtensionContext = this.context;
// ...
...
}
}
```
......@@ -47,7 +45,7 @@
export default class MyAbilityStage extends AbilityStage {
onCreate() {
let abilityStageContext = this.context;
// ...
...
}
}
```
......@@ -58,7 +56,7 @@
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
// ...
...
}
}
```
......@@ -94,8 +92,7 @@
获取路径的能力是基类Context中提供的能力,因此在ApplicationContext、AbilityStageContext、UIAbilityContext和ExtensionContext中均可以获取,在各类Context中获取到的路径会有一些差别,具体差别如下图所示。
**图1** Context中获取的应用开发路径
**图1** Context中获取的应用开发路径
![context-dir](figures/context-dir.png)
- 通过ApplicationContext获取的应用级别路径。应用全局信息建议存放的路径,存放在此路径的文件内容仅在应用卸载时会被删除。
......@@ -135,7 +132,7 @@ export default class EntryAbility extends UIAbility {
let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
// ...
...
}
}
```
......@@ -201,7 +198,7 @@ export default class EntryAbility extends UIAbility {
let bundleName2 = 'com.example.application';
let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label;
// ...
...
}
}
```
......@@ -223,7 +220,7 @@ export default class EntryAbility extends UIAbility {
let bundleName2 = 'com.example.application';
let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(bundleName2, moduleName2);
// ...
...
}
}
```
......@@ -237,7 +234,7 @@ export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(moduleName2);
// ...
...
}
}
```
......@@ -311,7 +308,7 @@ export default class EntryAbility extends UIAbility {
console.log(TAG, `register callback number: ${this.lifecycleId}`);
}
// ...
...
onDestroy() {
// 获取应用上下文
......
......@@ -37,7 +37,7 @@ Stage模型之所以成为主推模型,源于其设计思想。Stage模型的
Stage模型重新定义应用能力的边界,平衡应用能力和系统管控成本。
- 提供特定场景(如卡片、输入法)的应用组件,以便满足更多的使用场景。
- 提供特定场景(如服务卡片、输入法)的应用组件,以便满足更多的使用场景。
- 规范化后台进程管理:为保障用户体验,Stage模型对后台应用进程进行了有序治理,应用程序不能随意驻留在后台,同时应用后台行为受到严格管理,防止恶意应用行为。
......@@ -51,7 +51,7 @@ Stage模型之所以成为主推模型,源于其设计思想。Stage模型的
| 项目 | FA模型 | Stage模型 |
| -------- | -------- | -------- |
| **应用组件** | 1.&nbsp;组件分类<br/>![fa-model-component](figures/fa-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;PageAbility组件:包含UI界面,提供展示UI的能力。详细介绍请参见[PageAbility组件概述](pageability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ServiceAbility组件:提供后台服务的能力,无UI界面。详细介绍请参见[ServiceAbility组件概述](serviceability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;DataAbility组件:提供数据分享的能力,无UI界面。详细介绍请参见[DataAbility组件概述](dataability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;通过导出匿名对象、固定入口文件的方式指定应用组件。开发者无法进行派生,不利于扩展能力。 | 1.&nbsp;组件分类<br/>![stage-model-component](figures/stage-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;UIAbility组件:包含UI界面,提供展示UI的能力,主要用于和用户交互。详细介绍请参见[UIAbility组件概述](uiability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ExtensionAbility组件:提供特定场景(如卡片、输入法)的扩展能力,满足更多的使用场景。详细介绍请参见[ExtensionAbility组件概述](extensionability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;采用面向对象的方式,将应用组件以类接口的形式开放给开发者,可以进行派生,利于扩展能力。 |
| **应用组件** | 1.&nbsp;组件分类<br/>![fa-model-component](figures/fa-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;PageAbility组件:包含UI,提供展示UI的能力。详细介绍请参见[PageAbility组件概述](pageability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ServiceAbility组件:提供后台服务的能力,无UI。详细介绍请参见[ServiceAbility组件概述](serviceability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;DataAbility组件:提供数据分享的能力,无UI。详细介绍请参见[DataAbility组件概述](dataability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;通过导出匿名对象、固定入口文件的方式指定应用组件。开发者无法进行派生,不利于扩展能力。 | 1.&nbsp;组件分类<br/>![stage-model-component](figures/stage-model-component.png)&nbsp;&nbsp;&nbsp;-&nbsp;UIAbility组件:包含UI,提供展示UI的能力,主要用于和用户交互。详细介绍请参见[UIAbility组件概述](uiability-overview.md)。<br/>&nbsp;&nbsp;&nbsp;-&nbsp;ExtensionAbility组件:提供特定场景(如卡片、输入法)的扩展能力,满足更多的使用场景。详细介绍请参见[ExtensionAbility组件概述](extensionability-overview.md)。<br/>2.&nbsp;开发方式<br/>&nbsp;&nbsp;&nbsp;采用面向对象的方式,将应用组件以类接口的形式开放给开发者,可以进行派生,利于扩展能力。 |
| **进程模型** | 有两类进程:<br/>1.&nbsp;主进程<br/>2.&nbsp;渲染进程<br/>详细介绍请参见[进程模型](process-model-fa.md)。 | 有三类进程:<br/>1.&nbsp;主进程<br/>2.&nbsp;ExtensionAbility进程<br/>3.&nbsp;渲染进程<br/>详细介绍请参见[进程模型](process-model-stage.md)。 |
| **线程模型** | 1.&nbsp;ArkTS引擎实例的创建<br/>&nbsp;&nbsp;&nbsp;一个进程可以运行多个应用组件实例,每个应用组件实例运行在一个单独的ArkTS引擎实例中。<br/>2.&nbsp;线程模型<br/>&nbsp;&nbsp;&nbsp;每个ArkTS引擎实例都在一个单独线程(非主线程)上创建,主线程没有ArkTS引擎实例。<br/>3.&nbsp;进程内对象共享:不支持。<br/>详细介绍请参见[线程模型](thread-model-fa.md)。 | 1.&nbsp;ArkTS引擎实例的创建<br/>&nbsp;&nbsp;&nbsp;一个进程可以运行多个应用组件实例,所有应用组件实例共享一个ArkTS引擎实例。<br/>2.&nbsp;线程模型<br/>&nbsp;&nbsp;&nbsp;ArkTS引擎实例在主线程上创建。<br/>3.&nbsp;进程内对象共享:支持。<br/>详细介绍请参见[线程模型](thread-model-stage.md)。 |
| **任务管理模型** | -&nbsp;每个PageAbility组件实例创建一个任务。<br/>-&nbsp;任务会持久化存储,直到超过最大任务个数(根据产品配置自定义)或者用户主动删除任务。<br/>-&nbsp;PageAbility组件之间不会形成栈的结构。<br/>详细介绍请参见[任务管理场景介绍](mission-management-overview.md)。 | -&nbsp;每个UIAbility组件实例创建一个任务。<br/>-&nbsp;任务会持久化存储,直到超过最大任务个数(根据产品配置自定义)或者用户主动删除任务。<br/>-&nbsp;UIAbility组件之间不会形成栈的结构。<br/>详细介绍请参见[任务管理场景介绍](mission-management-overview.md)。 |
......
# 使用方刷新卡片内容(仅对系统应用开放)
当使用方添加了一些周期性刷新的卡片后,由于周期性刷新的时间间隔限制,可以在使用方中提供按钮主动触发卡片的刷新。这种场景下使用方可以通过调用[requestForm](../reference/apis/js-apis-app-form-formHost.md#requestform)接口请求卡片刷新,系统会调用卡片提供方FormExtensionAbility中的[onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform)生命周期回调,在回调中,可以使用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片内容。onUpdateForm生命周期回调参考[通过FormExtensionAbility刷新卡片内容](arkts-ui-widget-event-formextensionability.md)
当使用方添加了一些周期性刷新的卡片后,由于周期性刷新的时间间隔限制,可以在使用方中提供按钮主动触发卡片的刷新。这种场景下使用方可以通过调用[requestForm](../reference/apis/js-apis-app-form-formHost.md#requestform)接口请求卡片刷新,系统会调用卡片提供方FormExtensionAbility中的[onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform)生命周期回调,在回调中,可以使用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片内容。onUpdateForm生命周期回调参考[通过FormExtensionAbility刷新卡片内容](arkts-ui-widget-event-formextensionability.md)
```ts
import formHost from '@ohos.app.form.formHost';
......
......@@ -2,18 +2,15 @@
在已有的应用工程中,创建ArkTS卡片,具体的操作方式如下。
1. 创建卡片。
1. 创建卡片。
![WidgetProjectCreate1](figures/WidgetProjectCreate1.png)
2. 根据实际业务场景,选择一个卡片模板。
2. 根据实际业务场景,选择一个卡片模板。
![WidgetProjectCreate2](figures/WidgetProjectCreate2.png)
3. 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单击“Finish”,即可完成ArkTS卡片创建。
3. 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单击“Finish”,即可完成ArkTS卡片创建。
![WidgetProjectCreate3](figures/WidgetProjectCreate3.png)
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)。
![WidgetProjectView](figures/WidgetProjectView.png)
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)
![WidgetProjectView](figures/WidgetProjectView.png)
\ No newline at end of file
......@@ -52,13 +52,13 @@
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
function FunACall(data) {
// 获取call事件中传递的所有参数
console.log('FunACall param:' + JSON.stringify(data.readString()));
return null;
}
function FunBCall(data) {
console.log('FunACall param:' + JSON.stringify(data.readString()));
return null;
......@@ -67,23 +67,23 @@
export default class CameraAbility extends UIAbility {
// 如果UIAbility第一次启动,在收到call事件后会触发onCreate生命周期回调
onCreate(want, launchParam) {
try {
// 监听call事件所需的方法
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
}
try {
// 监听call事件所需的方法
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
}
}
// 进程退出时,解除监听
onDestroy() {
try {
this.callee.off('funA');
this.callee.off('funB');
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
}
try {
this.callee.off('funA');
this.callee.off('funB');
} catch (error) {
console.log('register failed with error. Cause: ' + JSON.stringify(error));
}
}
};
```
......@@ -4,7 +4,7 @@
在卡片页面中可以通过**postCardAction**接口触发message事件至FormExtensionAbility,然后由FormExtensionAbility刷新卡片内容,下面是这种刷新方式的简单示例。
- 在卡片页面通过注册Button的onClick点击事件回调,并在回调中调用**postCardAction**接口触发事件至FormExtensionAbility
- 在卡片页面通过注册Button的onClick点击事件回调,并在回调中调用**postCardAction**接口触发事件至FormExtensionAbility
```ts
let storage = new LocalStorage();
......@@ -34,7 +34,7 @@
}
```
- 在FormExtensionAbility的onFormEvent生命周期中调用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片
- 在FormExtensionAbility的onFormEvent生命周期中调用[updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform)接口刷新卡片
```ts
import formBindingData from '@ohos.app.form.formBindingData';
......@@ -57,10 +57,9 @@
})
}
// ...
...
}
```
运行效果如下图所示。
运行效果如下图所示。
![WidgetUpdatePage](figures/WidgetUpdatePage.png)
# 卡片事件能力说明
ArkTS卡片中提供了postCardAction()接口用于卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件,仅在卡片中可以调用。
ArkTS卡片中提供了postCardAction()接口用于卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件,仅在卡片中可以调用。
![WidgetPostCardAction](figures/WidgetPostCardAction.png)
......@@ -31,9 +28,7 @@ action参数说明:
| "params" | Object | 当前action携带的额外参数,内容使用JSON格式的键值对形式。"call"&nbsp;类型时需填入参数'method',且类型需要为string类型,用于触发UIAbility中对应的方法,必填。 |
postCardAction()接口示例代码:
`postCardAction()`接口示例代码:
```typescript
Button('跳转')
......@@ -49,8 +44,7 @@ Button('跳转')
}
});
})
```
```typescript
Button('拉至后台')
.width('40%')
.height('20%')
......@@ -67,7 +61,6 @@ Button('拉至后台')
})
```
以下是卡片开发过程中可以通过卡片事件实现的典型开发场景:
......
# 使用router事件跳转到指定页面
在卡片中使用**postCardAction**接口的router能力,能够快速拉起卡片提供方应用,因此页面较多的应用往往会通过卡片提供不同的跳转按钮,实现一键直达的效果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机应用的不同页面,从而提高用户的体验。
在卡片中使用**postCardAction**接口的router能力,能够快速拉起卡片提供方应用,因此页面较多的应用往往会通过卡片提供不同的跳转按钮,实现一键直达的效果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机应用的不同页面,从而提高用户的体验。
![WidgerCameraCard](figures/WidgerCameraCard.png)
......
......@@ -89,7 +89,7 @@
## 通过postCardAction接口触发call事件
- 在使用**postCardAction**接口的call事件时,需要在FormExtensionAbility中的onAddForm生命周期回调中更新formId。
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
......@@ -117,7 +117,7 @@
struct WidgetCard {
@LocalStorageProp('detail') detail: string = 'init';
@LocalStorageProp('formId') formId: string = '0';
build() {
Column() {
Button('拉至后台')
......@@ -150,8 +150,8 @@
import formProvider from '@ohos.app.form.formProvider';
import formInfo from '@ohos.app.form.formInfo';
const MSG_SEND_METHOD: string = 'funA'
const MSG_SEND_METHOD: string = 'funA';
// 在收到call事件后会触发callee监听的方法
function FunACall(data) {
// 获取call事件中传递的所有参数
......
......@@ -160,7 +160,7 @@
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
> - Image组件通过入参(**memory://fileName**)中的**memory://**标识来进行远端内存图片显示,其中**fileName**需要和EntryFormAbility传递对象(**'formImages': {key: fd})**中的**key**相对应。
>
> - Image组件通过传入的参数是否有变化来决定是否刷新图片,因此EntryFormAbility每次传递过来的**imgName**都需要不同,连续传递两个相同的**imgName**时,图片不会刷新。
# 卡片数据交互说明
ArkTS卡片框架提供了updateForm()接口和requestForm()接口主动触发卡片的页面刷新。
ArkTS卡片框架提供了updateForm()接口和requestForm()接口主动触发卡片的页面刷新。
![WidgetLocalStorageProp](figures/WidgetLocalStorageProp.png)
......
......@@ -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
@Entry
......@@ -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)
# 卡片页面能力说明
开发者可以使用声明式范式开发ArkTS卡片页面。如下卡片页面由DevEco Studio模板自动生成,开发者可以根据自身的业务场景进行调整。
开发者可以使用声明式范式开发ArkTS卡片页面。如下卡片页面由DevEco Studio模板自动生成,开发者可以根据自身的业务场景进行调整。
![WidgetPreviewPage](figures/WidgetPreviewPage.png)
......@@ -16,7 +13,6 @@ ArkTS卡片支持的页面能力详见[学习ArkTS语言](../quick-start/arkts-c
只有标识“支持在ArkTS卡片中使用”的接口可用于ArkTS卡片,同时请留意卡片场景下的能力差异说明。
例如:以下说明表示@Component装饰器可在ArkTS卡片中使用。
例如:以下说明表示@Component装饰器可在ArkTS卡片中使用。
![WidgetSupportApi](figures/WidgetSupportApi.png)
......@@ -166,6 +166,7 @@
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> **说明:**
>
> 通过本地数据库进行卡片信息的持久化时,建议先在[**onAddForm**](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform)生命周期中通过[**TEMPORARY_KEY**](../reference/apis/js-apis-app-form-formInfo.md#formparam)判断当前添加的卡片是否为常态卡片:如果是常态卡片,则直接进行卡片信息持久化;如果为临时卡片,则可以在卡片转为常态卡片(**[onCastToNormalForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#oncasttonormalform)**)时进行持久化;同时需要在卡片销毁(**[onRemoveForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onremoveform)**)时删除当前卡片存储的持久化信息,避免反复添加删除卡片导致数据库文件持续变大。
......@@ -91,7 +91,7 @@
在触发定时、定点或下次刷新后,系统会调用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点重置。
>
> 2. 当前定时刷新使用同一个计时器进行计时,因此卡片定时刷新的第一次刷新会有最多30分钟的偏差。比如第一张卡片A(每隔半小时刷新一次)在3点20分添加成功,定时器启动并每隔半小时触发一次事件,第二张卡片B(每隔半小时刷新一次)在3点40分添加成功,在3点50分定时器事件触发时,卡片A触发定时刷新,卡片B会在下次事件(4点20分)中才会触发。
......
......@@ -3,7 +3,7 @@
## 实现原理
**图1** ArkTS卡片实现原理  
**图1** ArkTS卡片实现原理
![WidgetPrinciple](figures/WidgetPrinciple.png)
- 卡片使用方:显示卡片内容的宿主应用,控制卡片在宿主中展示的位置,当前仅系统应用可以作为卡片使用方。
......@@ -14,7 +14,7 @@
- 卡片渲染服务:用于管理卡片渲染实例,渲染实例与卡片使用方上的[卡片组件](../reference/arkui-ts/ts-basic-components-formcomponent.md)一一绑定。卡片渲染服务运行卡片页面代码widgets.abc进行渲染,并将渲染后的数据发送至卡片使用方对应的[卡片组件](../reference/arkui-ts/ts-basic-components-formcomponent.md)
**图2** ArkTS卡片渲染服务运行原理  
**图2** ArkTS卡片渲染服务运行原理
![WidgetRender](figures/WidgetRender.png)
与JS卡片相比,ArkTS卡片支持在卡片中运行逻辑代码,为确保ArkTS卡片发生问题后不影响卡片使用方应用的使用,ArkTS卡片新增了卡片渲染服务用于运行卡片页面代码widgets.abc,卡片渲染服务由卡片管理服务管理。卡片使用方的每个卡片组件都对应了卡片渲染服务里的一个渲染实例,同一应用提供方的渲染实例运行在同一个虚拟机运行环境中,不同应用提供方的渲染实例运行在不同的虚拟机运行环境中,通过虚拟机运行环境隔离不同应用提供方卡片之间的资源与状态。开发过程中需要注意的是[globalThis](uiability-data-sync-with-ui.md#使用globalthis进行数据同步)对象的使用,相同应用提供方的卡片globalThis对象是同一个,不同应用提供方的卡片globalThis对象是不同的。
......@@ -25,11 +25,12 @@
卡片作为应用的一个快捷入口,ArkTS卡片相较于JS卡片具备如下几点优势:
- 统一开发范式,提升开发体验和开发效率。
OpenHarmony在2022年发布了声明式范式的UI开发框架,而卡片还延续了css/hml/json三段式类Web范式的开发方式,提高了开发者的学习成本,提供ArkTS卡片能力后,统一了卡片和页面的开发范式,页面的布局可以直接复用到卡片布局中,提升开发体验和开发效率。
**图3** 卡片工程结构对比  
**图3** 卡片工程结构对比
![WidgetProject](figures/WidgetProject.png)
- 增强了卡片的能力,使卡片更加万能。
- 新增了动效的能力:ArkTS卡片开放了[属性动画](../reference/arkui-ts/ts-animatorproperty.md)[显式动画](../reference/arkui-ts/ts-explicit-animation.md)的能力,使卡片的交互更加友好。
- 新增了自定义绘制的能力:ArkTS卡片开放了[Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md)画布组件,卡片可以使用自定义绘制的能力构建更多样的显示和交互效果。
......
......@@ -24,5 +24,5 @@ OpenHarmony通过CES(Common Event Service,公共事件服务)为应用程
每个应用都可以按需订阅公共事件,订阅成功,当公共事件发布时,系统会将其发送给对应的应用。这些公共事件可能来自系统、其他应用和应用自身。
**图1** 公共事件示意图
**图1** 公共事件示意图
![common-event](figures/common-event.png)
......@@ -25,13 +25,12 @@
2. 移除的粘性公共事件,必须是本应用之前已发布的粘性公共事件,发布粘性公共事件参考[公共事件发布](common-event-publish.md)章节。
```ts
CommonEventManager.removeStickyCommonEvent("sticky_event", (err) => { // sticky_event粘性公共事件名
if (err) {
console.info(`Remove sticky event AsyncCallback failed, errCode: ${err.code}, errMes: ${err.message}`);
return;
}
console.info(`Remove sticky event AsyncCallback success`);
}
commonEventManager.removeStickyCommonEvent("sticky_event", (err) => { // sticky_event粘性公共事件名
if (err) {
console.error(`Failed to remove sticky common event. Code is ${err.code}, message is ${err.message}`);
return;
}
console.info(`Succeeded in removeing sticky event.`);
});
```
......@@ -14,9 +14,9 @@
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
}
```
......@@ -29,7 +29,7 @@
```ts
{
"module": {
......
...
"extensionAbilities": [
{
"name": "StaticSubscriber",
......@@ -47,7 +47,7 @@
]
}
]
......
...
}
}
```
......
# 公共事件订阅概述
公共事件服务提供了动态订阅和静态订阅两种订阅方式。动态订阅与静态订阅最大的区别在于,动态订阅是应用运行时行为,而静态订阅是后台服务无需处于运行状态。
公共事件服务提供了动态订阅和静态订阅两种订阅方式。动态订阅与静态订阅最大的区别在于,动态订阅是应用运行时行为,而静态订阅是后台服务无需处于运行状态。
- 动态订阅:指订阅方在运行时调用公共事件订阅的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)
\ No newline at end of file
......@@ -12,8 +12,8 @@
| 接口名 | 接口描述 |
| -------- | -------- |
| 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 | 订阅公共事件 |
......@@ -32,7 +32,7 @@
let subscriber = null;
// 订阅者信息
let subscribeInfo = {
events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
events: ["usual.event.SCREEN_OFF"], // 订阅灭屏公共事件
}
```
......@@ -41,13 +41,13 @@
```ts
// 创建订阅者回调
commonEventManager.createSubscriber(subscribeInfo, (err, data) => {
if (err) {
console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] CreateSubscriber success`);
subscriber = data;
// 订阅公共事件回调
}
if (err) {
console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] CreateSubscriber success`);
subscriber = data;
// 订阅公共事件回调
}
})
```
......@@ -56,14 +56,14 @@
```ts
// 订阅公共事件回调
if (subscriber !== null) {
commonEventManager.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`);
}
})
commonEventManager.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`);
}
})
} else {
console.error(`[CommonEvent] Need create subscriber`);
console.error(`[CommonEvent] Need create subscriber`);
}
```
......@@ -2,4 +2,4 @@
应用配置文件中包含应用配置信息、应用组件信息、权限信息、开发者自定义信息等,这些信息在编译构建、分发和运行解决分别提供给编译工具、应用市场和操作系统使用。
在基于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
在基于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
......@@ -48,9 +48,9 @@ function implicitStartAbility() {
}
}
context.startAbility(wantInfo).then(() => {
// ...
...
}).catch((err) => {
// ...
...
})
}
```
......@@ -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)进行相应操作。
......
# 显式Want与隐式Want匹配规则
在启动目标Ability时,会通过显式Want或者隐式Want进行目标Ability的匹配,这里说的匹配规则就是调用方Want中设置的参数如何与目标Ability声明的配置文件进行匹配。
在启动目标应用组件时,会通过显式[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匹配原理如下表所示。
显式[Want](../reference/apis/js-apis-app-ability-want.md)匹配原理如下表所示。
| 名称 | 类型 | 匹配项 | 必选 | 规则 |
| -------- | -------- | -------- | -------- | -------- |
| deviceId | string | 是 | 否 | 留空将仅匹配本设备内Ability。 |
| deviceId | string | 是 | 否 | 留空将仅匹配本设备内的应用组件。 |
| bundleName | string | 是 | 是 | 如果指定abilityName,而不指定bundleName,则匹配失败。 |
| moduleName | string | 是 | 否 | 留空时当同一个应用内存在多个模块且模块间存在重名Ability,将默认匹配第一个。 |
| moduleName | string | 是 | 否 | 留空时当同一个应用内存在多个模块且模块间存在重名应用组件,将默认匹配第一个。 |
| abilityName | string | 是 | 是 | 该字段必须设置表示显式匹配。 |
| uri | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| type | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| action | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| entities | Array&lt;string&gt; | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标Ability。 |
| uri | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| type | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| action | string | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| entities | Array&lt;string&gt; | 否 | 否 | 系统匹配时将忽略该参数,但仍可作为参数传递给目标应用组件。 |
| flags | number | 否 | 否 | 不参与匹配,直接传递给系统处理,一般用来设置运行态信息,例如URI数据授权等。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标Ability。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标应用组件。 |
## 隐式Want匹配原理
隐式Want匹配原理如下表所示。
隐式[Want](../reference/apis/js-apis-app-ability-want.md)匹配原理如下表所示。
| 名称 | 类型 | 匹配项 | 必选 | 规则 |
| ----------- | ------------------------------ | ------ | ---- | ------------------------------------------------------------ |
......@@ -35,133 +35,128 @@
| action | string | 是 | 否 | |
| entities | Array&lt;string&gt; | 是 | 否 | |
| flags | number | 否 | 否 | 不参与匹配,直接传递给系统处理,一般用来设置运行态信息,例如URI数据授权等。 |
| parameters | {[key:&nbsp;string]:&nbsp;any} | 否 | 否 | 不参与匹配,应用自定义数据将直接传递给目标Ability。 |
| 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)
**图1** want参数的action匹配规则
![want-action](figures/want-action.png)
### want参数的entities匹配规则
将调用方传入的want参数的entities与待匹配Ability的skills配置中的entities进行匹配。
- 调用方传入的want参数的entities为空,待匹配Ability的skills配置中的entities不为空,则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不为空且包含调用方传入的want参数的entities,则entities匹配成功
- 调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities为空,则entities匹配失败
- 调用方传入的want参数的entities不为空,待匹配Ability的skills配置中的entities不为空且不完全包含调用方传入的want参数的entities,则entities匹配失败
- 调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities不为空且包含调用方传入的want参数的entities,则entities匹配成功
**图2** want参数的entities匹配规则
- 调用方传入的want参数的entities不为空,待匹配应用组件的skills配置中的entities不为空且不完全包含调用方传入的want参数的entities,则entities匹配失败。
![want-entities](figures/want-entities.png)
**图2** want参数的entities匹配规则
![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匹配规则)需要均匹配成功,则匹配成功,否则匹配失败。
最左uri匹配:当配置文件待匹配Ability的skills配置中的uris数组中只配置scheme;或者只配置scheme和host;或者只配置scheme,host和port时。
传入want参数的uri的最左边依次需要和scheme;或者scheme和host;或者scheme,host,port都匹配,才满足最左uri匹配。
1. 如果待匹配应用组件的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配应用组件的skills配置中的uris数组存在一条数据uri的scheme为空且[type匹配](#type匹配规则)成功,则匹配成功,否则匹配失败。
**图3** want参数中uri和type皆不为空时的匹配规则
- 调用方传入的want参数的uri和type都不为空,如下图所示。
1. 如果待匹配应用组件的skills配置中的uris数组为空,匹配失败。
2. 如果待匹配应用组件的skills配置中的uris数组存在一条数据[uri匹配](#uri匹配规则)[type匹配](#type匹配规则)需要均匹配成功,则匹配成功,否则匹配失败。
![want-uri-type1](figures/want-uri-type1.png)
最左uri匹配:当配置文件待匹配应用组件的skills配置中的uris数组中只配置scheme;或者只配置scheme和host;或者只配置scheme、host和port时。传入want参数的uri的最左边依次需要和scheme,或者scheme和host,或者scheme、host和port都匹配,才满足最左uri匹配。
**图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**正则表达式**时匹配成功,否则匹配失败
> **说明:**
> 待匹配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匹配规则
> **说明:**
> 此小节所述的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为空,则匹配失败。
......
......@@ -39,8 +39,7 @@ 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,8 +47,7 @@ ExtensionAbility组件是基于特定场景(例如服务卡片、输入法等
以实现卡片[FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md)为例进行说明。卡片框架提供了[FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md)基类,开发者通过派生此基类(如MyFormExtensionAbility),实现回调(如创建卡片的onCreate()回调、更新卡片的onUpdateForm()回调等)来实现具体卡片功能,具体见开发指导见[服务卡片FormExtensionAbility](service-widget-overview.md)
卡片FormExtensionAbility实现方不用关心使用方何时去请求添加、删除卡片,FormExtensionAbility实例及其所在的ExtensionAbility进程的整个生命周期,都是由卡片管理系统服务FormManagerService进行调度管理。
卡片FormExtensionAbility实现方不用关心使用方何时去请求添加、删除卡片,FormExtensionAbility实例及其所在的ExtensionAbility进程的整个生命周期,都是由卡片管理系统服务FormManagerService进行调度管理。
![form_extension](figures/form_extension.png)
......
......@@ -60,10 +60,10 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// ...
...
"continuable": true,
}
]
......
......@@ -63,7 +63,7 @@
// 其中createDeviceManager接口为系统API
deviceManager.createDeviceManager('ohos.samples.demo', (err, dm) => {
if (err) {
// ...
...
return
}
dmClass = dm
......@@ -83,7 +83,7 @@
}
```
4. 设置目标组件参数,调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)接口,启动UIAbility或ServiceExtensionAbility。
4. 设置目标组件参数,调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)接口,启动UIAbility或ServiceExtensionAbility。
```ts
let want = {
......@@ -94,9 +94,9 @@
}
// context为发起端UIAbility的AbilityContext
this.context.startAbility(want).then(() => {
// ...
...
}).catch((err) => {
// ...
...
})
```
......@@ -150,9 +150,9 @@
}
// context为发起端UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {
// ...
...
}).catch((err) => {
// ...
...
})
```
......@@ -170,7 +170,7 @@
}
// context为目标端UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {
// ...
...
});
```
......@@ -179,17 +179,17 @@
```ts
const RESULT_CODE: number = 1001;
// ...
...
// context为调用方UIAbility的UIAbilityContext
this.context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) {
// 解析目标端UIAbility返回的信息
let info = data.want?.parameters?.info
// ...
...
}
}).catch((err) => {
// ...
...
})
```
......
......@@ -344,7 +344,7 @@ InputMethodExtensionAbility通过[InputMethodExtensionContext](../reference/apis
```ts
{
"module": {
// ...
...
"extensionAbilities": [
{
"description": "inputMethod",
......
......@@ -14,12 +14,12 @@ Emitter的开发步骤如下:
// 定义一个eventId为1的事件
let event = {
eventId: 1
eventId: 1
};
// 收到eventId为1的事件后执行该回调
let callback = (eventData) => {
console.info('event callback');
console.info('event callback');
};
// 订阅eventId为1的事件
......@@ -30,21 +30,21 @@ Emitter的开发步骤如下:
```ts
import emitter from "@ohos.events.emitter";
// 定义一个eventId为1的事件,事件优先级为Low
let event = {
eventId: 1,
priority: emitter.EventPriority.LOW
eventId: 1,
priority: emitter.EventPriority.LOW
};
let eventData = {
data: {
"content": "c",
"id": 1,
"isEmpty": false,
}
data: {
"content": "c",
"id": 1,
"isEmpty": false,
}
};
// 发送eventId为1的事件,事件内容为eventData
emitter.emit(event, eventData);
```
......@@ -10,13 +10,13 @@ Worker的开发步骤如下:
1. 在工程的[模块级build-profile.json5](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-building-configuration-0000001218440654#section6887184182020)文件的buildOption属性中添加配置信息。
```ts
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/worker.ts"
]
}
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/worker.ts"
]
}
}
```
2. 根据build-profile.json5中的配置创建对应的worker.ts文件。
......@@ -28,9 +28,9 @@ Worker的开发步骤如下:
// 处理来自主线程的消息
parent.onmessage = function(message) {
console.info("onmessage: " + message)
// 发送消息到主线程
parent.postMessage("message from worker thread.")
console.info("onmessage: " + message)
// 发送消息到主线程
parent.postMessage("message from worker thread.")
}
```
......@@ -47,10 +47,10 @@ Worker的开发步骤如下:
// 处理来自worker线程的消息
wk.onmessage = function(message) {
console.info("message from worker: " + message)
console.info("message from worker: " + message)
// 根据业务按需停止worker线程
wk.terminate()
// 根据业务按需停止worker线程
wk.terminate();
}
```
......@@ -58,23 +58,22 @@ Worker的开发步骤如下:
```ts
import worker from '@ohos.worker';
let wk = new worker.ThreadWorker("../workers/worker.ts");
// 发送消息到worker线程
wk.postMessage("message from main thread.")
// 处理来自worker线程的消息
wk.onmessage = function(message) {
console.info("message from worker: " + message)
// 根据业务按需停止worker线程
wk.terminate()
console.info("message from worker: " + message)
// 根据业务按需停止worker线程
wk.terminate();
}
```
**说明:**
- build-profile.json5中配置的worker.ts的相对路径都为`./src/main/ets/workers/worker.ts`时,在Stage模型下创建worker需要传入路径`entry/ets/workers/worker.ts`;在FA模型下创建worker需要传入路径`../workers/worker.ts`
- 主线程与Worker线程间支持的数据类型参考[序列化支持类型](../reference/apis/js-apis-worker.md#序列化支持类型)
> **说明:**
>
> - build-profile.json5中配置的worker.ts的相对路径都为`./src/main/ets/workers/worker.ts`时,在Stage模型下创建worker需要传入路径`entry/ets/workers/worker.ts`;在FA模型下创建worker需要传入路径`../workers/worker.ts`。
> - 主线程与Worker线程间支持的数据类型参考[序列化支持类型](../reference/apis/js-apis-worker.md#序列化支持类型)。
......@@ -10,12 +10,12 @@
**图1** 任务与singleton模式
![mission-and-singleton](figures/mission-and-singleton.png)
- multiton:多实例模式,每次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法,都会在应用进程中创建一个该Ability的实例。
- multiton:多实例模式,每次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法,都会在应用进程中创建一个该UIAbility实例。
**图2** 任务与multiton模式
![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信息和任务快照)依然会保留,直到用户删除该任务。
> **说明:**
>
> specified模式只在Stage模型上支持,FA模型不支持。
......@@ -28,7 +28,7 @@
- 将一个指定的任务切换到前台。
一个UIAbility实例对应一个单独的任务,因此应用调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动一个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#配置文件权限声明)
......@@ -38,34 +38,34 @@
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// 任务销毁
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// 任务快照变化
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// 任务被移动到前台
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// 任务图标变化
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// 任务名称变化
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// 任务实例被关闭
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
// 任务创建
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// 任务销毁
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// 任务快照变化
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// 任务被移动到前台
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// 任务图标变化
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// 任务名称变化
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// 任务实例被关闭
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
// 1.注册任务变化通知
......@@ -73,56 +73,56 @@
// 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));
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
});
// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
console.info(err);
});
// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 5.获取低分辨任务快照
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
console.info("lockMission is called ");
});
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
console.info("unlockMission is called ");
});
// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
console.info("moveMissionToFront is called ");
});
// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
console.info("clearMission is called ");
});
// 9.删除全部任务
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
console.info(err);
});
// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
console.info("unregisterMissionListener");
})
```
......
......@@ -20,8 +20,10 @@
```ts
let imagePixelMap: PixelMap = undefined; // 需要获取图片PixelMap信息
this.context.setMissionIcon(imagePixelMap, (err) => {
console.error(`setMissionLabel failed, code is ${err.code}, message is ${err.message}`);
context.setMissionIcon(imagePixelMap, (err) => {
if (err.code) {
console.error(`Failed to set mission icon. Code is ${err.code}, message is ${err.message}`);
}
})
```
......@@ -36,9 +38,9 @@ this.context.setMissionIcon(imagePixelMap, (err) => {
```ts
this.context.setMissionLabel('test').then(() => {
console.info('setMissionLabel succeeded.');
console.info('Succeeded in seting mission label.');
}).catch((err) => {
console.error(`setMissionLabel failed, code is ${err.code}, message is ${err.message}`);
console.error(`Failed to set mission label. Code is ${err.code}, message is ${err.message}`);
});
```
......
......@@ -5,7 +5,7 @@
单个UIAbility组件可以实现多个页面,并在多个页面之间跳转,这种UIAbility组件内部的页面跳转关系称为“页面栈”,由ArkUI框架统一管理,如下图中的UIAbility1的Page1-&gt;Page2-&gt;Page3和UIAbility2的PageA-&gt;PageB-&gt;PageC。
**图1** 页面栈示意图  
**图1** 页面栈示意图
![mission-record](figures/mission-record.png)
- 页面栈的形成(下面2/3/5/6步骤为页面跳转,由ArkUI管理)
......@@ -41,11 +41,11 @@
MissionList任务链记录了任务之间的拉起关系,但是这个任务链可能会断开,有以下几种情况会导致任务链的断开:
- 进入任务列表,把任务链中间某个任务移动到前台。
- 进入任务列表,把任务链中间某个任务移动到前台。
![mission-chain1](figures/mission-chain1.png)
- 进入任务列表,把任务链中间某个任务清理掉。
- 进入任务列表,把任务链中间某个任务清理掉。
![mission-chain2](figures/mission-chain2.png)
- 单实例UIAbility的任务,被不同的任务反复拉起(AbilityB为单例)。
- 单实例UIAbility的任务,被不同的任务反复拉起(AbilityB为单例)。
![mission-chain3](figures/mission-chain3.png)
......@@ -17,13 +17,13 @@
```json
{
"module": {
// ...
...
"abilities": [
{
// singleton: 单实例模式
// standard: 多实例模式
"launchType": "standard",
// ...
...
}
]
}
......
# PageAbility组件概述
PageAbility是包含UI界面、提供展示UI能力的应用组件,主要用于与用户交互。
PageAbility是包含UI、提供展示UI能力的应用组件,主要用于与用户交互。
开发者通过DevEco Studio开发平台创建PageAbility时,DevEco Studio会自动创建相关模板代码。PageAbility相关能力通过单独的featureAbility实现,生命周期相关回调则通过app.js/app.ets中各个回调函数实现。
......@@ -22,11 +22,11 @@ PageAbility作为可见Ability,可以通过startAbility启动有界面的且
```ts
{
"module": {
// ...
...
"abilities": [
{
"visible": "true",
// ...
...
}
]
}
......
......@@ -6,8 +6,7 @@
## 服务卡片架构
**图1** 服务卡片架构
**图1** 服务卡片架构
![WidgetArchitecture](figures/WidgetArchitecture.png)
卡片的基本概念:
......@@ -24,8 +23,7 @@
卡片的常见使用步骤如下。
**图2** 卡片常见使用步骤
**图2** 卡片常见使用步
![WidgetUse](figures/WidgetUse.png)
1. 长按“桌面图标”,弹出操作菜单。
......@@ -55,4 +53,4 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上
| 自定义绘制 | 不支持 | 支持 |
| 逻辑代码执行(不包含import能力) | 不支持 | 支持 |
相比于JS卡片,ArkTS卡片在能力和场景方面更加丰富,因此无论开发何种用途的卡片,都推荐使用ArkTS卡片,因为它可以提高开发效率并实现动态化。但如果只需要做静态页面展示的卡片,可以考虑使用JS卡片。
推荐在开发需求需要动态能力的卡片时使用ArkTS卡片,因为它拥有更加丰富的能力和适应更多的场景,能够提高效率并实现动态化。但如果只需要静态展示卡片,可以考虑使用JS卡片。
# ServiceExtensionAbility
- [ServiceExtensionAbility](#serviceextensionability)
- [概述](#概述)
- [生命周期](#生命周期)
- [实现一个后台服务(仅对系统应用开放)](#实现一个后台服务仅对系统应用开放)
- [开发准备](#开发准备)
- [定义IDL接口](#定义idl接口)
- [创建ServiceExtensionAbility](#创建serviceextensionability)
- [启动一个后台服务(仅对系统应用开放)](#启动一个后台服务仅对系统应用开放)
- [连接一个后台服务](#连接一个后台服务)
- [客户端与服务端通信](#客户端与服务端通信)
- [服务端对客户端身份校验](#服务端对客户端身份校验)
- [相关示例](#相关示例)
- [概述](#概述)
- [生命周期](#生命周期)
- [实现一个后台服务(仅对系统应用开放)](#实现一个后台服务仅对系统应用开放)
- [开发准备](#开发准备)
- [定义IDL接口](#定义idl接口)
- [创建ServiceExtensionAbility](#创建serviceextensionability)
- [启动一个后台服务(仅对系统应用开放)](#启动一个后台服务仅对系统应用开放)
- [连接一个后台服务](#连接一个后台服务)
- [客户端与服务端通信](#客户端与服务端通信)
- [服务端对客户端身份校验](#服务端对客户端身份校验)
- [相关示例](#相关示例)
## 概述
......@@ -41,7 +40,7 @@
[ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md)提供了onCreate()、onRequest()、onConnect()、onDisconnect()和onDestory()生命周期回调,根据需要重写对应的回调方法。下图展示了ServiceExtensionAbility的生命周期。
**图1** ServiceExtensionAbility生命周期
**图1** ServiceExtensionAbility生命周期
![ServiceExtensionAbility-lifecycle](figures/ServiceExtensionAbility-lifecycle.png)
- **onCreate**
......@@ -182,7 +181,7 @@ export default class ServiceExtImpl extends IdlServiceExtStub {
```json
{
"module": {
// ...
...
"extensionAbilities": [
{
"name": "ServiceExtAbility",
......@@ -207,41 +206,43 @@ export default class ServiceExtImpl extends IdlServiceExtStub {
1. 在系统应用中启动一个新的ServiceExtensionAbility。示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)
```ts
let context = ...; // UIAbilityContext
let want = {
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "ServiceExtAbility"
"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"
"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}`);
})
```
......@@ -262,27 +263,27 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
```ts
let want = {
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "ServiceExtAbility"
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "ServiceExtAbility"
};
let options = {
onConnect(elementName, remote) {
/* 此处的入参remote为ServiceExtensionAbility在onConnect生命周期回调中返回的对象,
* 开发者通过这个对象便可以与ServiceExtensionAbility进行通信,具体通信方式见下文
*/
console.info('onConnect callback');
if (remote === null) {
console.info(`onConnect remote is null`);
return;
}
},
onDisconnect(elementName) {
console.info('onDisconnect callback')
},
onFailed(code) {
console.info('onFailed callback')
onConnect(elementName, remote) {
/* 此处的入参remote为ServiceExtensionAbility在onConnect生命周期回调中返回的对象,
* 开发者通过这个对象便可以与ServiceExtensionAbility进行通信,具体通信方式见下文
*/
console.info('onConnect callback');
if (remote === null) {
console.info(`onConnect remote is null`);
return;
}
},
onDisconnect(elementName) {
console.info('onDisconnect callback')
},
onFailed(code) {
console.info('onFailed callback')
}
}
// 建立连接后返回的Id需要保存下来,在解绑服务时需要作为参数传入
let connectionId = this.context.connectServiceExtensionAbility(want, options);
......@@ -293,9 +294,9 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
```ts
// connectionId为调用connectServiceExtensionAbility接口时的返回值,需开发者自行维护
this.context.disconnectServiceExtensionAbility(connectionId).then((data) => {
console.info('disconnectServiceExtensionAbility success');
console.info('disconnectServiceExtensionAbility success');
}).catch((error) => {
console.error('disconnectServiceExtensionAbility failed');
console.error('disconnectServiceExtensionAbility failed');
})
```
......@@ -310,27 +311,27 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
import IdlServiceExtProxy from '../IdlServiceExt/idl_service_ext_proxy';
let options = {
onConnect(elementName, remote) {
console.info('onConnect callback');
if (remote === null) {
console.info(`onConnect remote is null`);
return;
}
let serviceExtProxy = new IdlServiceExtProxy(remote);
// 通过接口调用的方式进行通信,屏蔽了RPC通信的细节,简洁明了
serviceExtProxy.processData(1, (errorCode, retVal) => {
console.log(`processData, errorCode: ${errorCode}, retVal: ${retVal}`);
});
serviceExtProxy.insertDataToMap('theKey', 1, (errorCode) => {
console.log(`insertDataToMap, errorCode: ${errorCode}`);
})
},
onDisconnect(elementName) {
console.info('onDisconnect callback')
},
onFailed(code) {
console.info('onFailed callback')
onConnect(elementName, remote) {
console.info('onConnect callback');
if (remote === null) {
console.info(`onConnect remote is null`);
return;
}
let serviceExtProxy = new IdlServiceExtProxy(remote);
// 通过接口调用的方式进行通信,屏蔽了RPC通信的细节,简洁明了
serviceExtProxy.processData(1, (errorCode, retVal) => {
console.log(`processData, errorCode: ${errorCode}, retVal: ${retVal}`);
});
serviceExtProxy.insertDataToMap('theKey', 1, (errorCode) => {
console.log(`insertDataToMap, errorCode: ${errorCode}`);
})
},
onDisconnect(elementName) {
console.info('onDisconnect callback')
},
onFailed(code) {
console.info('onFailed callback')
}
}
```
......@@ -338,40 +339,40 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
```ts
import rpc from '@ohos.rpc';
const REQUEST_CODE = 1;
let options = {
onConnect(elementName, remote) {
console.info('onConnect callback');
if (remote === null) {
console.info(`onConnect remote is null`);
return;
}
// 直接调用rpc的接口向服务端发送消息,客户端需自行对入参进行序列化,对返回值进行反序列化,操作繁琐
let option = new rpc.MessageOption();
let data = new rpc.MessageSequence();
let reply = new rpc.MessageSequence();
data.writeInt(100);
// @param code 表示客户端发送的服务请求代码。
// @param data 表示客户端发送的{@link MessageSequence}对象。
// @param reply 表示远程服务发送的响应消息对象。
// @param options 指示操作是同步的还是异步的。
//
// @return 如果操作成功返回{@code true}; 否则返回 {@code false}。
remote.sendMessageRequest(REQUEST_CODE, data, reply, option).then((ret) => {
let msg = reply.readInt();
console.info(`sendMessageRequest ret:${ret} msg:${msg}`);
}).catch((error) => {
console.info('sendMessageRequest failed');
});
},
onDisconnect(elementName) {
console.info('onDisconnect callback')
},
onFailed(code) {
console.info('onFailed callback')
onConnect(elementName, remote) {
console.info('onConnect callback');
if (remote === null) {
console.info(`onConnect remote is null`);
return;
}
// 直接调用rpc的接口向服务端发送消息,客户端需自行对入参进行序列化,对返回值进行反序列化,操作繁琐
let option = new rpc.MessageOption();
let data = new rpc.MessageSequence();
let reply = new rpc.MessageSequence();
data.writeInt(100);
// @param code 表示客户端发送的服务请求代码。
// @param data 表示客户端发送的{@link MessageSequence}对象。
// @param reply 表示远程服务发送的响应消息对象。
// @param options 指示操作是同步的还是异步的。
//
// @return 如果操作成功返回{@code true}; 否则返回 {@code false}。
remote.sendMessageRequest(REQUEST_CODE, data, reply, option).then((ret) => {
let msg = reply.readInt();
console.info(`sendMessageRequest ret:${ret} msg:${msg}`);
}).catch((error) => {
console.info('sendMessageRequest failed');
});
},
onDisconnect(elementName) {
console.info('onDisconnect callback')
},
onFailed(code) {
console.info('onFailed callback')
}
}
```
......@@ -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;
......@@ -402,7 +403,7 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
bundleManager.getBundleNameByUid(callerUid).then((callerBundleName) => {
console.info(TAG, 'getBundleNameByUid: ' + callerBundleName);
// 对客户端包名进行识别
if (callerBundleName != 'com.example.connectextapp') { // 识别不通过
if (callerBundleName != 'com.example.connectextapp') { // 识别不通过
console.info(TAG, 'The caller bundle is not in whitelist, reject');
return;
}
......@@ -430,15 +431,15 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
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;
const ERR_DENY = -1;
const TAG: string = "[IdlServiceExtImpl]";
export default class ServiceExtImpl extends IdlServiceExtStub {
processData(data: number, callback: processDataCallback): void {
console.info(TAG, `processData: ${data}`);
let callerTokenId = rpc.IPCSkeleton.getCallingTokenId();
let accessManger = abilityAccessCtrl.createAtManager();
// 所校验的具体权限由开发者自行选择,此处ohos.permission.SET_WALLPAPER只作为示例
......@@ -451,7 +452,7 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
}
callback(ERR_OK, data + 1); // 鉴权通过,执行正常业务逻辑
}
insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void {
// 开发者自行实现业务逻辑
console.log(TAG, `insertDataToMap, key: ${key} val: ${val}`);
......
......@@ -12,7 +12,7 @@
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)
......@@ -32,7 +32,7 @@
基于Stage模型开发应用时,在应用模型部分,涉及如下开发过程。
**表1** Stage模型开发流程
**表1** Stage模型开发流程
| 任务 | 简介 | 相关指导 |
| -------- | -------- | -------- |
......
......@@ -83,7 +83,7 @@ struct Index {
@State message: string = 'Hello World'
build() {
// ...
...
Button("startAbility")
.onClick(() => {
featureAbility.startAbility({
......@@ -98,7 +98,7 @@ struct Index {
console.info("startAbility failed errcode:" + err.code)
})
})
// ...
...
Button("page2")
.onClick(() => {
featureAbility.startAbility({
......@@ -113,7 +113,7 @@ struct Index {
console.info("startAbility failed errcode:" + err.code)
})
})
// ...
...
}
}
```
......@@ -136,7 +136,7 @@ export default {
})
},
onDestroy() {
// ...
...
},
}
```
......@@ -21,7 +21,7 @@ export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage) {
console.info("EntryAbility onWindowStageCreate")
windowStage.loadContent('pages/Index', (err, data) => {
// ...
...
});
let want = {
bundleName: "com.ohos.fa",
......@@ -66,7 +66,7 @@ export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage) {
console.info("EntryAbility onWindowStageCreate")
windowStage.loadContent('pages/Index', (err, data) => {
// ...
...
});
let want = {
bundleName: "com.ohos.fa",
......
......@@ -27,7 +27,7 @@ async function startServiceAbility() {
```
执行上述代码后,Ability将通过[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法来启动ServiceAbility。
执行上述代码后,Ability将通过[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法来启动ServiceAbility。
- 如果ServiceAbility尚未运行,则系统会先调用onStart()来初始化ServiceAbility,再回调Service的onCommand()方法来启动ServiceAbility。
......
......@@ -54,7 +54,7 @@
// 页面展示
build() {
// ...
...
}
}
```
......@@ -77,7 +77,7 @@
// 页面展示
build() {
// ...
...
}
}
```
......@@ -99,19 +99,19 @@ 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} `);
}
onCreate() {
systemLanguage = this.context.config.language; // Module首次加载时,获取系统当前语言
console.info(`systemLanguage is ${systemLanguage} `);
}
onConfigurationUpdate(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
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; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
if (systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
}
}
```
......@@ -131,21 +131,21 @@ 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} `);
}
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)}`);
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; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
if (systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // 将变化之后的系统语言保存,作为下一次变化前的系统语言
}
}
// ...
...
}
```
......@@ -163,11 +163,10 @@ ExtensionAbility组件提供了`onConfigurationUpdate()`回调方法用于订阅
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
export default class EntryFormAbility extends FormExtensionAbility {
onConfigurationUpdate(newConfig) {
console.info(`newConfig is ${JSON.stringify(newConfig)}`);
}
onConfigurationUpdate(newConfig) {
console.info(`newConfig is ${JSON.stringify(newConfig)}`);
}
// ...
...
}
```
......@@ -14,7 +14,7 @@
[基类Context](application-context-stage.md)中,提供了EventHub对象,使用EventHub实现UIAbility与UI之间的数据通信需要先获取EventHub对象。本章节将以此为例进行说明。
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)有如下两种调用方式,使用其中一种即可。
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';
......@@ -22,25 +22,25 @@
const TAG: string = '[Example].[Entry].[EntryAbility]';
export default class EntryAbility extends UIAbility {
func1(...data) {
// 触发事件,完成相应的业务操作
console.info(TAG, '1. ' + JSON.stringify(data));
}
onCreate(want, launch) {
// 获取eventHub
let eventhub = this.context.eventHub;
// 执行订阅操作
eventhub.on('event1', this.func1);
eventhub.on('event1', (...data) => {
// 触发事件,完成相应的业务操作
console.info(TAG, '2. ' + JSON.stringify(data));
});
}
func1(...data) {
// 触发事件,完成相应的业务操作
console.info(TAG, '1. ' + JSON.stringify(data));
}
onCreate(want, launch) {
// 获取eventHub
let eventhub = this.context.eventHub;
// 执行订阅操作
eventhub.on('event1', this.func1);
eventhub.on('event1', (...data) => {
// 触发事件,完成相应的业务操作
console.info(TAG, '2. ' + JSON.stringify(data));
});
}
}
```
2. 在UI界面中通过[eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit)方法触发该事件,在触发事件的同时,根据需要传入参数信息。
2. 在UI中通过[eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit)方法触发该事件,在触发事件的同时,根据需要传入参数信息。
```ts
import common from '@ohos.app.ability.common';
......@@ -62,7 +62,7 @@
// 页面展示
build() {
// ...
...
}
}
```
......@@ -89,9 +89,8 @@
globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对象,引擎内部的UIAbility/ExtensionAbility/Page都可以使用,因此可以使用globalThis对象进行数据同步。
**图1** 使用globalThis进行数据同步
![globalThis1](figures/globalThis1.png)
**图1** 使用globalThis进行数据同步
![globalThis1](figures/globalThis1.png)
如上图所示,下面从如下三个场景和一个注意点来介绍globalThis的使用:
......@@ -103,38 +102,38 @@ globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对
### UIAbility和Page之间使用globalThis
通过在globalThis对象上绑定属性/方法,可以实现UIAbility组件与UI之间的数据同步。例如在UIAbility组件中绑定want参数,即可在UIAbility对应的UI界面上使用want参数信息。
通过在globalThis对象上绑定属性/方法,可以实现UIAbility组件与UI之间的数据同步。例如在UIAbility组件中绑定want参数,即可在UIAbility对应的UI上使用want参数信息。
1. 调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动一个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';
export default class EntryAbility extends UIAbility {
onCreate(want, launch) {
globalThis.entryAbilityWant = want;
// ...
}
onCreate(want, launch) {
globalThis.entryAbilityWant = want;
...
}
// ...
...
}
```
2. 在UI界面中即可通过globalThis获取到want参数信息。
2. 在UI中即可通过globalThis获取到want参数信息。
```ts
let entryAbilityWant;
@Entry
@Component
struct Index {
aboutToAppear() {
entryAbilityWant = globalThis.entryAbilityWant;
}
// 页面展示
build() {
// ...
...
}
}
```
......@@ -150,10 +149,10 @@ globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对
import UIAbility from '@ohos.app.ability.UIAbility'
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.entryAbilityStr = 'UIAbilityA'; // UIAbilityA存放字符串“UIAbilityA”到globalThis
// ...
}
onCreate(want, launch) {
globalThis.entryAbilityStr = 'UIAbilityA'; // UIAbilityA存放字符串“UIAbilityA”到globalThis
...
}
}
```
......@@ -161,13 +160,13 @@ globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对
```ts
import UIAbility from '@ohos.app.ability.UIAbility'
export default class UIAbilityB extends UIAbility {
onCreate(want, launch) {
// UIAbilityB从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
// ...
}
onCreate(want, launch) {
// UIAbilityB从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
...
}
}
```
......@@ -182,11 +181,11 @@ globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对
import UIAbility from '@ohos.app.ability.UIAbility'
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
// UIAbilityA存放字符串“UIAbilityA”到globalThis
globalThis.entryAbilityStr = 'UIAbilityA';
// ...
}
onCreate(want, launch) {
// UIAbilityA存放字符串“UIAbilityA”到globalThis
globalThis.entryAbilityStr = 'UIAbilityA';
...
}
}
```
......@@ -194,21 +193,20 @@ globalThis是[ArkTS引擎实例](thread-model-stage.md)内部的一个全局对
```ts
import Extension from '@ohos.app.ability.ServiceExtensionAbility'
export default class ServiceExtAbility extends Extension {
onCreate(want) {
// ServiceExtAbility从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
// ...
}
onCreate(want) {
// ServiceExtAbility从globalThis读取name并输出
console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
...
}
}
```
### globalThis使用的注意事项
**图2** globalThis注意事项
**图2** globalThis注意事项
![globalThis2](figures/globalThis2.png)
- Stage模型下进程内的UIAbility组件共享ArkTS引擎实例,使用globalThis时需要避免存放相同名称的对象。例如UIAbilityA和UIAbilityB可以使用globalThis共享数据,在存放相同名称的对象时,先存放的对象会被后存放的对象覆盖。
......@@ -225,10 +223,10 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
import UIAbility from '@ohos.app.ability.UIAbility'
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) {
globalThis.context = this.context; // UIAbilityA存放context到globalThis
// ...
}
onCreate(want, launch) {
globalThis.context = this.context; // UIAbilityA存放context到globalThis
...
}
}
```
......@@ -243,7 +241,7 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
}
// 页面展示
build() {
// ...
...
}
}
```
......@@ -254,11 +252,11 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
import UIAbility from '@ohos.app.ability.UIAbility'
export default class UIAbilityB extends UIAbility {
onCreate(want, launch) {
// UIAbilityB覆盖了UIAbilityA在globalThis中存放的context
globalThis.context = this.context;
// ...
}
onCreate(want, launch) {
// UIAbilityB覆盖了UIAbilityA在globalThis中存放的context
globalThis.context = this.context;
...
}
}
```
......@@ -273,7 +271,7 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
}
// 页面展示
build() {
// ...
...
}
}
```
......@@ -284,10 +282,10 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
import UIAbility from '@ohos.app.ability.UIAbility'
export default class UIAbilityA extends UIAbility {
onCreate(want, launch) { // UIAbilityA从后台进入前台,不会再走这个生命周期
globalThis.context = this.context;
// ...
}
onCreate(want, launch) { // UIAbilityA从后台进入前台,不会再走这个生命周期
globalThis.context = this.context;
...
}
}
```
......@@ -302,7 +300,7 @@ Stage模型上同名对象覆盖导致问题的场景举例说明。
}
// 页面展示
build() {
// ...
...
}
}
```
......
......@@ -15,12 +15,12 @@ UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态
singleton启动模式为单实例模式,也是默认情况下的启动模式。
每次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
每次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
**图1** 单实例模式演示效果
![uiability-launch-type1](figures/uiability-launch-type1.gif)
> **说明**:应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例。由于启动的还是原来的UIAbility实例,并未重新创建一个新的UIAbility实例,此时只会进入该UIAbility的[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调,不会进入其[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
> **说明**:应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例。由于启动的还是原来的UIAbility实例,并未重新创建一个新的UIAbility实例,此时只会进入该UIAbility的[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调,不会进入其[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[`onWindowStageCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
如果需要使用singleton启动模式,在[module.json5配置文件](../quick-start/module-configuration-file.md)中的`launchType`字段配置为`singleton`即可。
......@@ -28,11 +28,11 @@ singleton启动模式为单实例模式,也是默认情况下的启动模式
```json
{
"module": {
// ...
...
"abilities": [
{
"launchType": "singleton",
// ...
...
}
]
}
......@@ -42,7 +42,7 @@ singleton启动模式为单实例模式,也是默认情况下的启动模式
## multiton启动模式
multiton启动模式为多实例模式,每次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
multiton启动模式为多实例模式,每次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
**图2** 多实例模式演示效果
![uiability-launch-type2](figures/uiability-launch-type2.gif)
......@@ -53,11 +53,11 @@ multiton启动模式的开发使用,在[module.json5配置文件](../quick-sta
```json
{
"module": {
// ...
...
"abilities": [
{
"launchType": "multiton",
// ...
...
}
]
}
......@@ -79,67 +79,68 @@ specified启动模式为指定实例模式,针对一些特殊场景使用(
```json
{
"module": {
// ...
...
"abilities": [
{
"launchType": "specified",
// ...
...
}
]
}
}
```
2. 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用[startAbility()](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用[startAbility()](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,可以在`want`参数中增加一个自定义参数,例如`instanceKey`,以此来区分不同的UIAbility实例。
2. 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用[`startAbility()`](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用[`startAbility()`](.../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法时,可以在`want`参数中增加一个自定义参数,例如`instanceKey`,以此来区分不同的UIAbility实例。
```ts
// 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
// 例如在文档使用场景中,可以用文档路径作为Key标识
function getInstance() {
// ...
...
}
let context = ...; // context为调用方UIAbility的UIAbilityContext
let want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'SpecifiedAbility',
moduleName: 'module1', // moduleName非必选
parameters: { // 自定义信息
instanceKey: getInstance(),
},
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'SpecifiedAbility',
moduleName: 'specified', // moduleName非必选
parameters: { // 自定义信息
instanceKey: getInstance(),
},
}
// context为调用方UIAbility的UIAbilityContext
this.context.startAbility(want).then(() => {
// ...
context.startAbility(want).then(() => {
console.info('Succeeded in starting ability.');
}).catch((err) => {
// ...
console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`);
})
```
3. 由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的[onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)回调函数和[onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)回调函数。
3. 由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)回调函数和[`onWindowStageCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)回调函数。
示例代码中,通过实现[onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调函数,解析传入的`want`参数,获取自定义参数`instanceKey`。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。
示例代码中,通过实现[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)生命周期回调函数,解析传入的`want`参数,获取自定义参数`instanceKey`。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。
```ts
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage {
onAcceptWant(want): string {
// 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
// 当前示例指的是module1 Module的SpecifiedAbility
if (want.abilityName === 'SpecifiedAbility') {
// 返回的字符串Key标识为自定义拼接的字符串内容
return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
}
return '';
onAcceptWant(want): string {
// 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
// 当前示例指的是module1 Module的SpecifiedAbility
if (want.abilityName === 'SpecifiedAbility') {
// 返回的字符串Key标识为自定义拼接的字符串内容
return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
}
return '';
}
}
```
> **说明:**
>
> 1. 当应用的UIAbility实例已经被创建,并且配置为指定实例模式时,如果再次调用[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例,且[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md)的[onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)回调匹配到一个已创建的UIAbility实例,则系统会启动原来的UIAbility实例,并且不会重新创建一个新的UIAbility实例。此时,该UIAbility实例的[onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调会被触发,而不会触发[onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
> 1. 当应用的UIAbility实例已经被创建,并且配置为指定实例模式时,如果再次调用[`startAbility()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法启动该UIAbility实例,且[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md)的[`onAcceptWant()`](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)回调匹配到一个已创建的UIAbility实例,则系统会启动原来的UIAbility实例,并且不会重新创建一个新的UIAbility实例。此时,该UIAbility实例的[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调会被触发,而不会触发[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)和[`onWindowStageCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate)生命周期回调。
> 2. DevEco Studio默认工程中未自动生成AbilityStage,AbilityStage文件的创建请参见[AbilityStage组件容器](abilitystage.md)。
例如在文档应用中,可以为不同的文档实例内容绑定不同的Key值。每次新建文档时,可以传入一个新的Key值(例如可以将文件的路径作为一个Key标识),此时AbilityStage中启动UIAbility时都会创建一个新的UIAbility实例;当新建的文档保存之后,回到桌面,或者新打开一个已保存的文档,回到桌面,此时再次打开该已保存的文档,此时AbilityStage中再次启动该UIAbility时,打开的仍然是之前原来已保存的文档界面。
......
......@@ -7,9 +7,8 @@
UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示。
**图1** UIAbility生命周期状态
![Ability-Life-Cycle](figures/Ability-Life-Cycle.png)
**图1** UIAbility生命周期状态
![Ability-Life-Cycle](figures/Ability-Life-Cycle.png)
## 生命周期状态说明
......@@ -17,18 +16,17 @@ UIAbility的生命周期包括Create、Foreground、Background、Destroy四个
### Create状态
Create状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用onCreate()回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI界面展示。
Create状态为在应用加载过程中,UIAbility实例创建完成时触发,系统会调用`onCreate()`回调。可以在该回调中进行应用初始化操作,例如变量定义资源加载等,用于后续的UI展示。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 应用初始化
}
// ...
onCreate(want, launchParam) {
// 应用初始化
}
...
}
```
......@@ -36,60 +34,60 @@ export default class EntryAbility extends UIAbility {
### 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()](../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)(获焦/失焦、可见/不可见)。
在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';
export default class EntryAbility extends UIAbility {
// ...
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));
...
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;
}
// 设置UI界面加载
windowStage.loadContent('pages/Index', (err, data) => {
// ...
});
});
} catch (exception) {
console.error('Failed to enable the listener for window stage event changes. Cause:' +
JSON.stringify(exception));
}
// 设置UI加载
windowStage.loadContent('pages/Index', (err, data) => {
...
});
}
}
```
> **说明:**
>
> WindowStage的相关使用请参见[窗口开发指导](../windowmanager/application-window-stage.md)。
对应于onWindowStageCreate()回调。在UIAbility实例销毁之前,则会先进入onWindowStageDestroy()回调,可以在该回调中释放UI界面资源。例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件。
对应于`onWindowStageCreate()`回调。在UIAbility实例销毁之前,则会先进入`onWindowStageDestroy()`回调,可以在该回调中释放UI资源。例如在`onWindowStageDestroy()`中注销获焦/失焦等WindowStage事件。
```ts
......@@ -97,57 +95,54 @@ import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
windowStage: window.WindowStage;
// ...
onWindowStageCreate(windowStage: window.WindowStage) {
this.windowStage = windowStage;
// ...
}
onWindowStageDestroy() {
// 释放UI界面资源
// 例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件
try {
this.windowStage.off('windowStageEvent');
} catch (exception) {
console.error('Failed to disable the listener for window stage event changes. Cause:' +
JSON.stringify(exception));
};
}
windowStage: window.WindowStage;
...
onWindowStageCreate(windowStage: window.WindowStage) {
this.windowStage = windowStage;
...
}
onWindowStageDestroy() {
// 释放UI资源
// 例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件
try {
this.windowStage.off('windowStageEvent');
} catch (err) {
console.error(`Failed to disable the listener for window stage event changes. Code is ${err.code}, message is ${err.message}`);
};
}
}
```
### Foreground和Background状态
Foreground和Background状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于onForeground()回调和onBackground()回调。
Foreground和Background状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于`onForeground()`回调和`onBackground()`回调。
onForeground()回调,在UIAbility的UI界面可见之前,如UIAbility切换至前台时触发。可以在onForeground()回调中申请系统需要的资源,或者重新申请在onBackground()中释放的资源。
`onForeground()`回调,在UIAbility的UI可见之前,如UIAbility切换至前台时触发。可以在`onForeground()`回调中申请系统需要的资源,或者重新申请在`onBackground()`中释放的资源。
onBackground()回调,在UIAbility的UI界面完全不可见之后,如UIAbility切换至后台时候触发。可以在onBackground()回调中释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
`onBackground()`回调,在UIAbility的UI完全不可见之后,如UIAbility切换至后台时候触发。可以在`onBackground()`回调中释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
例如应用在使用过程中需要使用用户定位时,假设应用已获得用户的定位权限授权。在UI界面显示之前,可以在onForeground()回调中开启定位功能,从而获取到当前的位置信息。
例如应用在使用过程中需要使用用户定位时,假设应用已获得用户的定位权限授权。在UI显示之前,可以在`onForeground()`回调中开启定位功能,从而获取到当前的位置信息。
当应用切换到后台状态,可以在onBackground()回调中停止定位功能,以节省系统的资源消耗。
当应用切换到后台状态,可以在`onBackground()`回调中停止定位功能,以节省系统的资源消耗。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
// ...
...
onForeground() {
// 申请系统需要的资源,或者重新申请在onBackground中释放的资源
}
onForeground() {
// 申请系统需要的资源,或者重新申请在onBackground()中释放的资源
}
onBackground() {
// 释放UI界面不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
onBackground() {
// 释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作
// 例如状态保存等
}
}
```
......@@ -156,17 +151,16 @@ export default class EntryAbility extends UIAbility {
Destroy状态在UIAbility实例销毁时触发。可以在onDestroy()回调中进行系统资源的释放、数据的保存等操作。
例如调用terminateSelf()方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。
例如调用`terminateSelf()`方法停止当前UIAbility实例,从而完成UIAbility实例的销毁;或者用户使用最近任务列表关闭该UIAbility实例,完成UIAbility的销毁。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
// ...
...
onDestroy() {
// 系统资源的释放、数据的保存等
}
onDestroy() {
// 系统资源的释放、数据的保存等
}
}
```
......@@ -3,22 +3,23 @@
## 概述
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)
关于UIAbility的设计理念,请详细参考[Stage模型的设计理念](application-model-description.md)
UIAbility划分原则与建议:
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下
- 如果开发者希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
......@@ -32,7 +33,7 @@ UIAbility组件是系统调度的基本单元,为应用提供绘制界面的
```json
{
"module": {
// ...
...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
......@@ -42,7 +43,7 @@ UIAbility组件是系统调度的基本单元,为应用提供绘制界面的
"label": "$string:EntryAbility_label", // UIAbility组件的标签
"startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
// ...
...
}
]
}
......
......@@ -6,7 +6,7 @@ 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
......@@ -14,14 +14,14 @@ import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
windowStage.loadContent('pages/Index', (err, data) => {
// ...
});
}
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
windowStage.loadContent('pages/Index', (err, data) => {
...
});
}
// ...
...
}
```
......@@ -31,23 +31,22 @@ export default class EntryAbility extends UIAbility {
## 获取UIAbility的上下文信息
UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类的实例,[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类拥有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如startAbility()、connectServiceExtensionAbility()、terminateSelf()等)。
UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类的实例,[UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md)类拥有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext可以获取UIAbility的相关配置信息,如包代码路径、Bundle名称、Ability名称和应用程序需要的环境状态等属性信息,以及可以获取操作UIAbility实例的方法(如`startAbility()``connectServiceExtensionAbility()``terminateSelf()`等)。
- 在UIAbility中可以通过this.context获取UIAbility实例的上下文信息。
- 在UIAbility中可以通过`this.context`获取UIAbility实例的上下文信息。
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// 获取UIAbility实例的上下文
let context = this.context;
// ...
}
onCreate(want, launchParam) {
// 获取UIAbility实例的上下文
let context = this.context;
...
}
}
```
- 在页面中获取UIAbility实例的上下文信息,包括导入依赖资源context模块和在组件中定义一个context变量两个部分。
```ts
......@@ -67,7 +66,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
// 页面展示
build() {
// ...
...
}
}
```
......@@ -92,7 +91,7 @@ UIAbility类拥有自身的上下文信息,该信息为[UIAbilityContext](../r
// 页面展示
build() {
// ...
...
}
}
```
......@@ -5,7 +5,7 @@
[Want](../reference/apis/js-apis-app-ability-want.md)是一种对象,用于在应用组件之间传递信息。
其中,一种常见的使用场景是作为[startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability)方法的参数。例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。
其中,一种常见的使用场景是作为[`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)
......@@ -13,38 +13,40 @@
## Want的类型
- **显式Want**:在启动Ability时,如果指定了abilityName和bundleName,则称为显式Want。
显式Want通常用于在当前应用中启动已知的目标Ability,通过提供目标Ability所在应用的Bundle名称信息(bundleName)并在Want对象内指定abilityName来启动目标Ability。当有明确处理请求的对象时,显式Want是一种简单有效的启动目标Ability的方式。
- **显式Want**:在启动目标应用组件时,调用方传入的want参数中指定了abilityName和bundleName,称为显式Want。
显式Want通常用于在当前应用中启动已知的目标应用组件,通过提供目标应用组件所在应用的Bundle名称信息(bundleName)并在Want对象内指定abilityName来启动目标应用组件。当有明确处理请求的对象时,显式Want是一种简单有效的启动目标应用组件的方式。
```ts
let wantInfo = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility',
}
```
- **隐式Want**:在启动Ability时,如果未指定abilityName,则称为隐式Want。
- **隐式Want**:在启动目标应用组件时,调用方传入的want参数中未指定abilityName,称为隐式Want。
当需要处理的对象不明确时,可以使用隐式Want,在当前应用中使用其他应用提供的某个能力,而不关心提供该能力的具体应用。隐式Want使用[skills标签](../quick-start/module-configuration-file.md#skills标签)来定义需要使用的能力,并由系统匹配声明支持该请求的所有应用来处理请求。例如,需要打开一个链接的请求,系统将匹配所有声明支持该请求的应用,然后让用户选择使用哪个应用打开链接。
```ts
let wantInfo = {
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.search',
// entities can be omitted
entities: [ 'entity.system.browsable' ],
uri: 'https://www.test.com:8080/query/student',
type: 'text/plain',
// uncomment line below if wish to implicitly query only in the specific bundle.
// bundleName: 'com.example.myapplication',
action: 'ohos.want.action.search',
// entities can be omitted
entities: [ 'entity.system.browsable' ],
uri: 'https://www.test.com:8080/query/student',
type: 'text/plain',
};
```
> **说明:**
> - 根据系统中待匹配Ability的匹配情况不同,使用隐式Want启动Ability时会出现以下三种情况。
> - 未匹配到满足条件的Ability:启动失败。
> - 匹配到一个满足条件的Ability:直接启动该Ability
> - 匹配到多个满足条件的Ability(UIAbility):弹出选择框让用户选择。
> - 根据系统中待匹配应用组件的匹配情况不同,使用隐式Want启动应用组件时会出现以下三种情况。
> - 未匹配到满足条件的应用组件:启动失败。
> - 匹配到一个满足条件的应用组件:直接启动该应用组件
> - 匹配到多个满足条件的应用组件(UIAbility):弹出选择框让用户选择。
>
> - 调用方传入的want参数中不带有abilityName和bundleName,则不允许通过隐式Want启动所有应用的ServiceExtensionAbility。
>
......
......@@ -121,48 +121,48 @@ FA卡片开发,即基于[FA模型](fa-model-development-overview.md)的卡片
```ts
export default {
onCreate(want) {
console.info('FormAbility onCreate');
// 使用方创建卡片时触发,提供方需要返回卡片数据绑定类
let obj = {
"title": "titleOnCreate",
"detail": "detailOnCreate"
};
let formData = formBindingData.createFormBindingData(obj);
return formData;
},
onCastToNormal(formId) {
// 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理
console.info('FormAbility onCastToNormal');
},
onUpdate(formId) {
// 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新
console.info('FormAbility onUpdate');
let obj = {
"title": "titleOnUpdate",
"detail": "detailOnUpdate"
};
let formData = formBindingData.createFormBindingData(obj);
formProvider.updateForm(formId, formData).catch((error) => {
console.info('FormAbility updateForm, error:' + JSON.stringify(error));
});
},
onVisibilityChange(newStatus) {
// 使用方发起可见或者不可见通知触发,提供方需要做相应的处理,仅系统应用生效
console.info('FormAbility onVisibilityChange');
},
onEvent(formId, message) {
// 若卡片支持触发事件,则需要重写该方法并实现对事件的触发
console.info('FormAbility onEvent');
},
onDestroy(formId) {
// 删除卡片实例数据
console.info('FormAbility onDestroy');
},
onAcquireFormState(want) {
console.info('FormAbility onAcquireFormState');
return formInfo.FormState.READY;
},
onCreate(want) {
console.info('FormAbility onCreate');
// 使用方创建卡片时触发,提供方需要返回卡片数据绑定类
let obj = {
"title": "titleOnCreate",
"detail": "detailOnCreate"
};
let formData = formBindingData.createFormBindingData(obj);
return formData;
},
onCastToNormal(formId) {
// 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理
console.info('FormAbility onCastToNormal');
},
onUpdate(formId) {
// 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新
console.info('FormAbility onUpdate');
let obj = {
"title": "titleOnUpdate",
"detail": "detailOnUpdate"
};
let formData = formBindingData.createFormBindingData(obj);
formProvider.updateForm(formId, formData).catch((error) => {
console.info('FormAbility updateForm, error:' + JSON.stringify(error));
});
},
onVisibilityChange(newStatus) {
// 使用方发起可见或者不可见通知触发,提供方需要做相应的处理,仅系统应用生效
console.info('FormAbility onVisibilityChange');
},
onEvent(formId, message) {
// 若卡片支持触发事件,则需要重写该方法并实现对事件的触发
console.info('FormAbility onEvent');
},
onDestroy(formId) {
// 删除卡片实例数据
console.info('FormAbility onDestroy');
},
onAcquireFormState(want) {
console.info('FormAbility onAcquireFormState');
return formInfo.FormState.READY;
},
}
```
......@@ -186,15 +186,15 @@ FA卡片开发,即基于[FA模型](fa-model-development-overview.md)的卡片
```json
"js": [{
"name": "widget",
"pages": ["pages/index/index"],
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"type": "form"
}]
"js": [{
"name": "widget",
"pages": ["pages/index/index"],
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"type": "form"
}]
```
- abilities模块,用于对应卡片的FormAbility,内部字段结构说明:
......@@ -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)
......@@ -361,7 +361,7 @@ onUpdate(formId) {
![widget-development-fa](figures/widget-development-fa.png)
> **说明:**
> FA模型当前仅支持JS扩展的类Web开发范式来实现卡片的UI界面
> FA模型当前仅支持JS扩展的类Web开发范式来实现卡片的UI。
- HML:使用类Web范式的组件描述卡片的页面信息。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册