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

!5858 Stage模型ability开发及call开发回合3.2beta1分支

Merge pull request !5858 from 张亚菲/zyfBeta
# Ability开发指导
## 场景介绍
Stage模型是区别于FA模型的一种应用开发模型,对此模型的介绍详见[Stage模型综述](stage-brief.md)。开发Stage模型应用时,需要在module.json和app.json配置文件中对应用的包结构进行声明,对应用包结构配置文件的说明详见[应用包结构配置文件的说明](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/stage-structure.md)。基于Stage模型的Ability应用开发,主要涉及如下功能逻辑:
- 创建Page Ability应用,如视频播放、新闻资讯等,需要通过屏幕进行浏览的应用,以及支持人机交互。
- 获取Ability的配置信息,如ApplicationInfo、AbilityInfo及HapModuleInfo等。
- 启动/带参数启动/带返回结果启动/带AccountId启动其他Ability。
- 应用向用户申请授权。
- 系统环境变化通知给AbilityStage及Ability。
- 创建支持使用屏幕浏览及人机交互的Ability应用,包括实现Ability的生命周期、获取Ability配置信息、向用户申请授权及环境变化通知等场景。
- 启动Ability应用,包括相同设备启动Ability、跨设备启动Ability以及指定页面启动Ability等场景。
- 通用组件Call功能,详见[Call调用开发指导](stage-call.md)
- 连接ServiceExtensionAbility,与ServiceExtensionAbility断开连接,详见[ServiceExtensionAbility开发指导](stage-serviceextension.md)
- 应用迁移,详见[应用迁移开发指导](stage-ability-continuation.md)
### 启动模式
ability支持单实例、多实例和指定实例3种启动模式。
在module.json中通过launchType配置项,可以配置具体的启动模式,其中:
ability支持单实例、多实例和指定实例3种启动模式,在module.json中通过launchType配置。启动模式对应Ability被启动时的行为,对启动模式的详细说明如下:
| 启动模式 | 描述 |说明 |
| ----------- | ------- |---------------- |
......@@ -20,50 +16,43 @@ ability支持单实例、多实例和指定实例3种启动模式。
| singleton | 单实例 | 系统中只存在唯一一个实例,startAbility时,如果已存在,则复用系统中的唯一一个实例 |
| specified | 指定实例 | 运行时由ability内部业务决定是否创建多实例 |
缺省情况下是singleton模式。
## 接口说明
缺省情况下是singleton模式,module.json示例如下:
```json
{
"module": {
"abilities": [
{
"launchType": "singleton",
}
]
}
}
```
## 创建Ability
### 接口说明
AbilityStage功能如下(AbilityStage类,拥有context属性,具体的API详见[接口文档](../reference/apis/js-apis-application-abilitystage.md)):
**表1** AbilityStage API接口功能介绍
|接口名|描述|
|:------|:------|
|void onCreate()|AbilityStage初始化时被调用。|
|string onAcceptWant(want: Want)|启动指定Ability时被调用。|
|void onConfigurationUpdated(config: Configuration)|全局配置发生变更时被调用。|
|onCreate(): void|AbilityStage初始化时被调用。|
|onAcceptWant(want: Want): string|启动指定Ability时被调用。|
|onConfigurationUpdated(config: Configuration): void|全局配置发生变更时被调用。|
Ability功能如下(Ability类,具体的API详见[接口文档](../reference/apis/js-apis-application-ability.md)):
**表2** Ability API接口功能介绍
|接口名|描述|
|:------|:------|
|void onCreate(want: Want, param: AbilityConstant.LaunchParam)|Ability生命周期回调,Ability启动时被调用。|
|void onDestroy()|Ability生命周期回调,Ability销毁时被调用。|
|void onWindowStageCreate(windowStage: window.WindowStage)|Ability生命周期回调,创建window stage时被调用,应用开发者可通过window.WindowStage的接口执行页面加载等操作。|
|void onWindowStageDestroy()|Ability生命周期回调,销毁window stage时被调用。|
|void onForeground()|Ability生命周期回调,Ability切换至前台时被调用。|
|void onBackground()|Ability生命周期回调,Ability切换至后台时被调用。|
|void onNewWant(want: Want)|Ability回调,Ability的启动模式设置为单例时被调用。|
|void onConfigurationUpdated(config: Configuration)|Ability回调,Ability的系统配置更新时被调用。|
Ability类拥有context属性,context属性为AbilityContext类,AbilityContext类拥有abilityInfo、currentHapModuleInfo等属性,具体的API详见[接口文档](../reference/apis/js-apis-ability-context.md)
**表3** AbilityContext API接口功能介绍
|接口名|描述|
|:------|:------|
|void startAbility(want: Want, callback: AsyncCallback\<void>)|启动Ability。|
|void startAbility(want: Want, options: StartOptions, callback: AsyncCallback\<void>)|启动Ability。|
|void startAbilityWithAccount(want: Want, accountId: number, callback: AsyncCallback\<void>)|带AccountId启动Ability。|
|void startAbilityWithAccount(want: Want, accountId: number, options: StartOptions, callback: AsyncCallback\<void>)|带AccountId启动Ability。|
|void startAbilityForResult(want: Want, callback: AsyncCallback\<AbilityResult>)|带返回结果启动Ability。|
|void startAbilityForResult(want: Want, options: StartOptions, callback: AsyncCallback\<AbilityResult>)|带返回结果启动Ability。|
|void startAbilityForResultWithAccount(want: Want, accountId: number, callback: AsyncCallback\<AbilityResult>)|带返回结果及AccountId启动Ability。|
|void startAbilityForResultWithAccount(want: Want, accountId: number, options: StartOptions, callback: AsyncCallback\<void>)|带返回结果及AccountId启动Ability。|
|void terminateSelf(callback: AsyncCallback\<void>)|销毁当前的Page Ability。|
|void terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback\<void>)|带返回结果销毁当前的Page Ability。|
## 开发步骤
### 创建Page Ability应用
|onCreate(want: Want, param: AbilityConstant.LaunchParam): void|Ability生命周期回调,Ability启动时被调用。|
|onDestroy(): void|Ability生命周期回调,Ability销毁时被调用。|
|onWindowStageCreate(windowStage: window.WindowStage): void|Ability生命周期回调,创建window stage时被调用,应用开发者可通过window.WindowStage的接口执行页面加载等操作。|
|onWindowStageDestroy(): void|Ability生命周期回调,销毁window stage时被调用。|
|onForeground(): void|Ability生命周期回调,Ability切换至前台时被调用。|
|onBackground(): void|Ability生命周期回调,Ability切换至后台时被调用。|
|onNewWant(want: Want): void|Ability回调,Ability的启动模式设置为单例时被调用。|
|onConfigurationUpdated(config: Configuration): void|Ability回调,Ability的系统配置更新时被调用。|
### 实现AbilityStage及Ability生命周期
创建Stage模型的Page Ability应用,需实现AbilityStage接口及Ability生命周期接口,并使用窗口提供的方法设置页面。具体示例代码如下:
1. 导入AbilityStage模块。
```
......@@ -155,8 +144,81 @@ export default class MainAbility extends Ability {
}
}
```
### 应用向用户申请授权
应用需要获取用户的隐私信息或使用系统能力时,比如获取位置信息、使用相机拍摄照片或录制视频等,需要向用户申请授权。在开发过程中,首先需要明确涉及的敏感权限并在module.json中声明需要的权限,同时通过接口`requestPermissionsFromUser`以动态弹窗的方式向用户申请授权。以访问日历为例,具体示例代码如下:
### 启动Ability
在module.json声明需要的权限:
```json
"requestPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
}
]
```
通过动态弹窗向用户申请授权:
```ts
let context = this.context
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions).then((data) => {
console.log("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.log("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
### 系统环境变化通知
环境变化,包括全局配置的变化和Ability配置的变化。全局配置指全局的、系统的配置,目前包括“语言”和“颜色模式”,全局配置的变化一般由“设置”中的配置项或“控制中心”中的图标触发。Ability配置指与单个Ability实例相关的配置,目前包括“displayId”、“屏幕分辨率”,“横竖屏”,这些配置与Ability所在的Display有关,Ability配置的变化一般由窗口触发。配置项目前均定义在[Configuration](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-configuration.md)类中。
对于Stage模型的应用,配置发生变化时,不会重启Ability,会触发应用的`onConfigurationUpdated(config: Configuration)`回调,若应用希望根据配置变化做相应处理,可以重写`onConfigurationUpdated`回调,若无需处理配置变化,则可以不必实现`onConfigurationUpdated`回调。应该注意的是,回调中的Configuration对象包括当前Ability所有的配置,不仅是发生变化的配置。
如下示例展示了AbilityStage的`onConfigurationUpdated`回调实现,系统语言和颜色模式发生变化时触发该回调。具体示例代码如下:
```ts
import Ability from '@ohos.application.Ability'
import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
export default class MyAbilityStage extends AbilityStage {
onConfigurationUpdated(config) {
if (config.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) {
console.log('colorMode changed to dark')
}
}
}
```
如下示例展示了Ability的`onConfigurationUpdated`回调实现,系统语言、颜色模式以及Display相关的参数,比如方向、Density,发生变化时触发该回调。具体示例代码如下:
```ts
import Ability from '@ohos.application.Ability'
import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
export default class MainAbility extends Ability {
direction : number;
onCreate(want, launchParam) {
this.direction = this.context.config.direction
}
onConfigurationUpdated(config) {
if (this.direction !== config.direction) {
console.log(`direction changed to ${config.direction}`)
}
}
}
```
## 启动Ability
### 接口说明
Ability类拥有context属性,context属性为AbilityContext类,AbilityContext类拥有abilityInfo、currentHapModuleInfo等属性,启动Ability等方法。具体的API详见[接口文档](../reference/apis/js-apis-ability-context.md)
**表3** AbilityContext API接口功能介绍
|接口名|描述|
|:------|:------|
|startAbility(want: Want, callback: AsyncCallback\<void>): void|启动Ability。|
|startAbility(want: Want, options?: StartOptions): Promise\<void>|启动Ability。|
|startAbilityWithAccount(want: Want, accountId: number, callback: AsyncCallback\<void>): void|带AccountId启动Ability。|
|startAbilityWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\<void>|带AccountId启动Ability。|
|startAbilityForResult(want: Want, callback: AsyncCallback\<AbilityResult>): void|带返回结果启动Ability。|
|startAbilityForResult(want: Want, options?: StartOptions): Promise\<AbilityResult>|带返回结果启动Ability。|
|startAbilityForResultWithAccount(want: Want, accountId: number, callback: AsyncCallback\<AbilityResult>): void|带返回结果及AccountId启动Ability。|
|startAbilityForResultWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\<AbilityResult>|带返回结果及AccountId启动Ability。|
### 相同设备启动Ability
应用可以通过`this.context`获取Ability实例的上下文,进而使用AbilityContext中的StartAbility相关接口启动Ability。启动Ability可指定Want、StartOptions、accountId,通过callback形式或promise形式实现。具体示例代码如下:
```ts
let context = this.context
......@@ -165,11 +227,7 @@ var want = {
"bundleName": "com.example.MyApplication",
"abilityName": "MainAbility"
};
var options = {
windowMode: 0,
displayId: 2
};
context.startAbility(want, options).then((data) => {
context.startAbility(want).then((data) => {
console.log("Succeed to start ability with data: " + JSON.stringify(data))
}).catch((error) => {
console.error("Failed to start ability with error: "+ JSON.stringify(error))
......@@ -209,69 +267,8 @@ function getRemoteDeviceId() {
}
}
```
### 应用向用户申请授权
应用需要某些权限如存储、位置信息、访问日历时,需要向用户申请授权。明确需要申请的权限后,在`module.json`中添加待申请的权限,同时通过接口`requestPermissionsFromUser`以动态弹窗的方式向用户申请授权。以访问日历为例,具体示例代码如下:
module.json的修改:
```json
"requestPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
}
]
```
通过动态弹窗向用户申请授权:
```ts
let context = this.context
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions).then((data) => {
console.log("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.log("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
在跨设备场景下,需要向用户申请数据同步的权限。具体示例代码如下:
```ts
let context = this.context
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => {
console.log("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.log("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
### 系统环境变化通知给AbilityStage及Ability
全局配置,比如系统语言和颜色模式发生变化时,通过`onConfigurationUpdated`接口通知给AbilityStage和Ability。系统应用可以通过`updateConfiguration`接口更新系统语言和颜色模式。如下示例展示了AbilityStage的`onConfigurationUpdated`回调实现,系统语言和颜色模式发生变化时触发该回调。具体示例代码如下:
```ts
import Ability from '@ohos.application.Ability'
import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
export default class MyAbilityStage extends AbilityStage {
onConfigurationUpdated(config) {
console.log("MyAbilityStage onConfigurationUpdated")
console.log("MyAbilityStage config language" + config.language)
console.log("MyAbilityStage config colorMode" + config.colorMode)
}
}
```
如下示例展示了Ability的`onConfigurationUpdated`回调实现,系统语言、颜色模式以及Display相关的参数,比如方向、Density,发生变化时触发该回调。具体示例代码如下:
```ts
import Ability from '@ohos.application.Ability'
import ConfigurationConstant from '@ohos.application.ConfigurationConstant'
export default class MainAbility extends Ability { {
onConfigurationUpdated(config) {
console.log("MainAbility onConfigurationUpdated")
console.log("MainAbility config language" + config.language)
console.log("MainAbility config colorMode" + config.colorMode)
console.log("MainAbility config direction" + config.direction)
console.log("MainAbility config screenDensity" + config.screenDensity)
console.log("MainAbility config displayId" + config.displayId)
}
}
```
### 通过onNewWant实现指定页面启动Ability
向用户申请数据同步'ohos.permission.DISTRIBUTED_DATASYNC'的权限。申请授权示例代码见[应用向用户申请授权](###应用向用户申请授权)
### 指定页面启动Ability
当Ability的启动模式设置为单例时,若Ability已被拉起,再次启动Ability会触发onNewWant回调。应用开发者可以通过want传递启动参数,比如希望指定页面启动Ability,可以通过want中的uri参数或parameters参数传递pages信息。目前,Stage模型中Ability暂时无法直接使用router的能力,可以将启动参数传递给自定义组件,在自定义组件的生命周期中调用router接口显示指定页面。具体示例代码如下:
使用startAbility再次拉起Ability,通过want中的uri参数传递页面信息:
......
......@@ -4,7 +4,7 @@ Ability Call调用是Ability能力的扩展,它为Ability提供一种能够被
- 创建Callee被调用端。
- 访问Callee被调用端。
本文中的Caller和Callee分别表示调用者和被调用者,Call调用流程示意图如下。
本文中的Caller和Callee分别表示调用者和被调用者,IPC表示进程间通信,Call调用流程示意图如下。
![stage-call](figures/stage-call.png)
......@@ -18,15 +18,17 @@ Caller及Callee功能如下:具体的API详见[接口文档](../reference/apis
**表1** Call API接口功能介绍
|接口名|描述|
|:------|:------|
|Promise<Caller> startAbilityByCall(want: Want)|获取指定通用组件的Caller通信接口,拉起指定通用组件并将其切换到后台。|
|void on(method: string, callback: CalleeCallBack)|Callee.on,通用组件Callee注册method对应的callback方法。|
|void off(method: string)|Callee.off,通用组件Callee去注册method的callback方法。|
|Promise<void> call(method: string, data: rpc.Sequenceable)|Caller.call,向通用组件Callee发送约定序列化数据。|
|Promise<rpc.MessageParcel> callWithResult(method: string, data: rpc.Sequenceable)|Caller.callWithResult,向通用组件Callee发送约定序列化数据, 并将返回的约定序列化数据带回。|
|void release()|Caller.release,释放通用组件的Caller通信接口。|
|void onRelease(callback: OnReleaseCallBack)|Caller.onRelease,注册通用组件通信断开监听通知。|
|startAbilityByCall(want: Want): Promise\<Caller>|获取指定通用组件的Caller通信接口,拉起指定通用组件并将其切换到后台。|
|on(method: string, callback: CaleeCallBack): void|通用组件Callee注册method对应的callback方法。|
|off(method: string): void|通用组件Callee去注册method的callback方法。|
|call(method: string, data: rpc.Sequenceable): Promise\<void>|向通用组件Callee发送约定序列化数据。|
|callWithResult(method: string, data: rpc.Sequenceable): Promise\<rpc.MessageParcel>|向通用组件Callee发送约定序列化数据, 并将返回的约定序列化数据带回。|
|release(): void|释放通用组件的Caller通信接口。|
|onRelease(callback: OnReleaseCallBack): void|注册通用组件通信断开监听通知。|
## 开发步骤
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 开发步骤章节中的示例代码片段是开发过程的步骤化展示,部分代码可能无法单独运行,完整工程代码请参考[相关实例](##相关实例)。
### 创建Callee被调用端
Callee被调用端,需要实现指定方法的数据接收回调函数、数据的序列化及反序列化方法。在需要接收数据期间,通过on接口注册监听,无需接收数据时通过off接口解除监听。
1. 配置Ability的启动模式
......@@ -200,7 +202,7 @@ context.requestPermissionsFromUser(permissions).then((data) => {
```
3. 发送约定序列化数据
向被调用端发送Sequenceable数据有两种方式,一种是不带返回值,一种是获取被调用端返回的数据,method以及序列化数据需要与被调用端协商一致。如下示例调用Call接口,向Callee被调用端发送数据。具体示例代码如下:
向被调用端发送Sequenceable数据有两种方式,一种是不带返回值,一种是获取被调用端返回的数据,method以及序列化数据需要与被调用端协商一致。如下示例调用Call接口,向Callee被调用端发送数据。具体示例代码如下:
```ts
const MSG_SEND_METHOD: string = 'CallSendMsg'
async onButtonCall() {
......@@ -235,7 +237,7 @@ async onButtonCallWithResult(originMsg, backMsg) {
```
4. 释放Caller通信接口
Caller不再使用后,应用开发者可以通过release接口释放Caller。具体示例代码如下:
Caller不再使用后,应用开发者可以通过release接口释放Caller。具体示例代码如下:
```ts
try {
this.caller.release()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册