OpenHarmony应用开发-FA模型切换Stage模型指导
版本:v3.2 Beta5
模型切换概述
本文介绍如何将一个FA模型开发的声明式范式应用切换到Stage模型,您需要完成如下动作:
- 工程切换:新建一个Stage模型的应用工程。
- 配置文件切换:config.json切换为app.json5和module.json5。
- 组件切换:PageAbility/ServiceAbility/DataAbility切换为UIAbility和ExtensionAbility(图片仅展示了FA模型的PageAbility切换成Stage模型的UIAbility:下图左侧为FA模型,app.ets为FA模型的PageAbility组件;下图右侧为Stage模型,EntryAbility.ts为Stage模型的UIAbility组件)。
- 卡片切换:将FA模型的FormAbility切换为Stage模型的FormExtensionAbility(下图中的Service Widget在FA中为FormAbility,在Stage中为FormExtensionAbility)。
- API切换:将FA模型应用中使用到的FAModelOnly接口切换为Stage模型下的推荐接口和写法。
配置文件的差异
FA模型应用在config.json文件中描述应用的基本信息,一个应用工程中可以创建多个Module,每个Module中都有一份config.json文件。config.json由app、deviceConfig和module三部分组成,app标签用于配置应用级别的属性,如果一个应用有多个Module,需要由开发者保证各个config.json文件中app标签配置的一致性。
Stage模型应用在app.json5和module.json文件中描述应用的基本信息,和FA模型应用类似,一个Stage模型应用工程中同样可以创建多个[Module],但是一个应用工程中仅存在一份app.json5,用于配置应用级别的属性,对每个Module都生效;每个Module中都有一份module.json5配置文件,用于配置Module级别的属性,仅对当前Module生效。
图1 配置文件差异
app和deviceConfig的切换
为了便于开发者维护应用级别的属性配置,Stage模型将config.json中的app和deviceConfig标签提取到了app.json5中进行配置,并对部分标签名称进行了修改,具体差异见下表。
表1 配置文件app标签差异对比
配置项 | FA模型配置文件config.json中app标签 | Stage模型配置文件app.json5中app标签 |
应用的版本号 | “version”: { “code”: 1, } | “versionCode”: 1 , |
标识版本号的文字描述,用于向用户展示 | “version”: { “name”: “1.0.0”, } | “versionName” : “1.0.0” , |
标识应用可兼容的最低版本号 | “version”: { “minCompatibleVersionCode”: 1, } | “minCompatibleVersionCode” : 1 , |
运行应用所需要的最低API版本 | “apiVersion”: { “compatible”: 7, } | “minAPIVersion” : 7 , |
应用运行所需的目标API版本 | “apiVersion”: { “target”: 8, } | “targetApiVersion” : 8 , |
应用运行所需的目标API版本的类型 | “apiVersion”: { “releaseType”: Release, } | “apiReleaseType”: “Release” , |
app.json5中对原先config.json中的deviceConfig标签进行了重构,将deviceConfig下的标签的设备信息整合到了app.json5的app标签下,具体差异见下表
表2 配置文件deviceConfig标签差异对比
FA中deviceConfig标签 | 描述 | stage模型中 | 差异比对 |
deviceConfig标签 | deviceConfig标签配置了设备信息 | / | Stage模型中没有该标签,直接在app标签下配置设备信息 |
process | 标识应用或者Ability的进程名。如果在deviceConfig标签下配置了process标签,则该应用的所有Ability都运行在这个进程中。如果在abilities标签下也为某个Ability配置了process标签,则该Ability就运行在这个进程中。 | / | Stage模型不支持配置进程名称 |
keepAlive | 标识应用是否始终保持运行状态,仅支持系统应用配置,三方应用配置不生效。 | / | Stage模型不支持系统应用模型管控方式变更 |
supportBackup | 标识应用是否支持备份和恢复。 | / | Stage模型不支持 |
compressNativeLibs | 标识libs库是否以压缩存储的方式打包到HAP包。 | / | Stage模型不支持 |
network | 标识网络安全性配置。 | / | Stage模型不支持 |
module的切换
从FA模型切换到Stage模型时,开发者需要将config.json文件module标签下的配置迁移到module.json5配置文件module标签下,具体差异见下列表格。
表1 FA模型module标签与Stage模型module标签差异对比
FA标签 | 标签说明 | 对应的Stage标签 | 差异说明 |
mainAbility | 服务中心图标露出的ability,常驻进程拉起时会启动mainAbility。 | mainElement | 标签名称变更,Stage模型不在使用.符号。 |
package | 标识HAP的包结构名称,在应用内保证唯一性。 | / | Stage模型使用name来保证应用唯一性。 |
name | 标识HAP的类名 | / | FA模型中实际未使能,Stage模型没有与之对应的标签。 |
supportedModes | 标识应用支持的运行模式,当前只定义了驾驶模式(drive) | / | Stage模型已废弃。 |
distro对象中的moduleName | 标识当前HAP的名称 distro对象中的moduleName | name | 标签变更。 |
distro对象中的moduleType | 标识当前HAP的类型,包括两种类型:entry和feature。另外,如果表示HAR包类型,请设置为har | type | 标签变更。 |
distro对象中的installationFree | 标识当前HAP是否支持免安装特性 | installationFree | 标签变更。 |
distro对象中的deliveryWithInstall | 标识当前HAP是否支持随应用安装 | deliveryWithInstall | 标签变更。 |
metaData | 标识HAP的元信息 | metadata | 具体差异如表2。 |
abilities | 标识当前模块内的所有Ability | abilities | 具体差异如表5。 |
js | 标识基于ArkUI框架开发的JS模块集合,其中的每个元素代表一个JS模块的信息 | pages | Stage模型在module标签下保留该对象中的pages,window配置与pages的下一级。 |
shortcuts | 标识应用的快捷方式信息 | shortcut_config.json文件 | 在开发视图的resources/base/profile下面定义配置文件shortcut_config.json。 |
reqPermissions | 标识应用运行时向系统申请的权限 | requestPermissions | 标签名称变更。 |
colorMode | 标识应用自身的颜色模式 | / | Stage模型不支持。 |
distroFilter | 标识应用的分发规则 | distroFilter_config.json文件 | Stage模型在开发视图的resources/base/profile下面定义配置文件distroFilter_config.json。 |
reqCapabilities | 标识运行应用程序所需的设备能力 | / | Stage模型不支持。 |
commonEvents | 公共事件 | common_event_config.json文件 | Stage模型在开发视图的resources/base/profile下面定义配置文件common_event_config.json。 |
entryTheme | 此标签标识OpenHarmony内部主题的关键字 | / | Stage模型不支持。 |
表2 FA模型metaData和Stage中metadata对比
FA标签 | 标签说明 | 对应的Stage模型标签 | 差异对比 |
parameters | 标识调用Ability时所有调用参数的元信息 | / | Stage模型不支持。 |
results | 标识Ability返回值的元信息 | / | Stage模型不支持。 |
customizeData | 该标签标识父级组件的自定义元信息,Parameters和results在application不可配 | metadata | 具体差异见表3。 |
表3 FA模型metaData的customizeData和Stage中metadata对比
FA标签 | 标签说明 | 对应的Stage模型标签 | 差异对比 |
name | 标识数据项的键名称。字符串最大长度为255字节 | name | 无。 |
value | 标识数据项的值。字符串最大长度为255字节。 | value | 无。 |
extra | 标识当前custom数据的格式,取值为表示extra的资源值。 | resource | 标签变更。具体实例见表4。 |
表4 FA模型metaData和Stage中metadata示例
FA模型示例 | Stage模型示例 |
“meteData”: { “customizeDate”: [{ “name”: “label”, “value”: “string”, “extra”: “$string:label”, }] } | “meteData”: [{ “name”: “label”, “value”: “string”, “resource”: “$string:label”, }] |
表5 FA模型和Stage中abilities差异对比
FA模型的abilities对象标签 | 描述 | Stage模型中abilities对象标签 | 差异对比 |
process | 运行应用程序或Ability的进程名称 | / | Stage模型不支持abilities中配置,在module标签下配置process |
uri | 标识Ability的统一资源标识符 | / | Stage模型不支持 |
deviceCapability | 标识Ability运行时要求设备具有的能力,采用字符串数组的格式表示 | / | Stage模型不支持 |
metaData | 该标签标识ability的元信息。 | metadata | 具体差异如表2 |
type | 标识Ability的类型 | / | Stage模型不支持 |
grantPermission | 指定是否可以向Ability内任何数据授予权限 | / | abilities内不支持; |
readPermission | 标识读取Ability的数据所需的权限。该标签仅适用于data类型的Ability | / | abilities内不支持;在extensionAbilities标签中支持 |
writePermission | 标识向Ability写数据所需的权限 | / | abilities内不支持;在extensionAbilities标签中支持 |
configChanges | 标识Ability关注的系统配置集合 | / | Stage模型不支持 |
mission | 标识Ability指定的任务栈 | / | Stage模型不支持 |
targetAbility | 标识当前Ability重用的目标Ability | / | Stage模型不支持 |
multiUserShared | 标识Ability是否支持多用户状态进行共享,该标签仅适用于data类型的Ability | / | Stage模型不支持 |
supportPipMode | 标识Ability是否支持用户进入PIP模式(用于在页面最上层悬浮小窗口,俗称"画中画",常见于视频播放等场景) | / | Stage模型不支持 |
formsEnabled | 标识Ability是否支持卡片(forms)功能 | / | Stage模型不支持 |
forms | 标识服务卡片的属性。该标签仅当formsEnabled为"true"时,才能生效 | form_config.json文件 | Stage模型在开发视图的resources/base/profile下面定义配置文件form_config.json |
srcLanguage | Ability开发语言的类型 | / | Stage模型不支持 |
srcPath | 该标签标识Ability对应的JS组件代码路径 | srcEntrance | 该标签标识ability所对应的js代码路径。 |
uriPermission | 标识该Ability有权访问的应用程序数据 | / | Stage模型不支持 |
PageAbility切换
FA模型中PageAbility对应Stage模型中的UIAbility。切换步骤如下。
- 在Stage应用中创建UIAbility。
- 将FA应用中PageAbility的代码迁移到新创建的UIAbility中。 FA应用中PageAbility和Stage应用中的UIAbility生命周期基本一致,两者的生命周期详细对比见下表。
FA的PageAbility | Stage的UIAbility | 对应关系描述 |
onCreate(): void | onCreate(want: Want, param: AbilityConstant.LaunchParam): void | 两者的意义和调用时机一致,Stage模型在回调中新增了参数,方便开发者在创建的时候获取启动相关的数据。 |
NA | onWindowStageCreate(windowStage: window.WindowStage): void | Stage模型新增,窗口创建时由系统回调。 |
onActive(): void | on(eventType: ‘windowStageEvent’, callback: Callback<WindowStageEventType>): void; WindowStageEventType.ACTIVE | 两者的意义和调用时机一致。Stage模型下移动到了窗口对象中。 |
onShow(): void | onForeground(): void | 两者的意义和调用时机一致,参数也一致。 |
onNewWant(want: Want): void | onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void | 两者的意义和调用时机一致,Stage模型多了LaunchParam参数来告知应用启动原因。 |
onInactive(): void | on(eventType: ‘windowStageEvent’, callback: Callback<WindowStageEventType>): void; WindowStageEventType.INACTIVE | 两者的意义和调用时机一致。Stage模型下移动到了窗口对象中。 |
onHide(): void | onBackground(): void | 两者的意义和调用时机一致,参数也一致。 |
NA | onWindowStageDestroy(): void | Stage模型新增,窗口销毁时由系统回调。 |
onDestroy(): void | onDestroy(): void | 两者的意义和调用时机一致,参数也一致。 |
- 对迁移过来的代码进行调整,主要有以下两部分。 1、指定加载页面的方式不同。
- 在FA模型中,通过在config.json中设置页面信息来配置需要加载的页面。
- 在Stage模型中,则是通过在onWindowStageCreate回调中调用windowStage.loadContent实现对页面的加载。
例如,开发者希望Ability启动后加载"pages/Index"页面,在FA模型中,开发者需要在config.json中加入如下代码:
"pages" : [
"pages/Index"
]
在Stage模型中,则在MainAbility中实现如下接口:
import Window from '@ohos.window'
onWindowStageCreate(windowStage: Window.WindowStage) {
// Main window is created, set main page for this ability
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
console.error("loadContent failed")
return;
}
});
}
ServiceAbility切换
FA模型中的ServiceAbility对应Stage模型中的ServiceExtensionAbility。Stage模型下的ServiceExtensionAbility为系统API,只有系统应用才可以创建。因此,FA模型的ServiceAbility的切换,对于系统应用和三方应用策略有所不同。下面分别介绍这两种场景。
系统应用ServiceAbility切换
目前系统提供了ServiceExtensionAbility供系统应用使用。切换步骤和PageAbility基本一致。
- 在Stage应用中创建ServiceExtensionAbility。
- 将FA应用中ServiceAbility的业务代码迁移到新创建的ServiceExtensionAbility中。 ServiceAbility和ServiceExtensionAbility生命周期对比见下表。
FA的ServiceAbility | Stage的ServiceExtensionAbility | 对比描述 |
onStart(): void | onCreate(want: Want): void | 两者调用时机一致,Stage模型下增加了入参want以便开发者在创建时获取参数。 |
onCommand(want: Want, startId: number): void | onRequest(want: Want, startId: number): void | 两者意义和调用时机一致,参数也一致。 |
onConnect(want: Want): rpc.RemoteObject | onConnect(want: Want): rpc.RemoteObject | 两者意义和调用时机一致,参数也一致。 |
onDisconnect(want: Want): void | onDisconnect(want: Want): void | 两者意义和调用时机一致,参数也一致。 |
onReconnect(want: Want): void | onReconnect(want: Want): void | 两者意义和调用时机一致,参数也一致。 |
onStop(): void | onDestroy(): void | 两者意义和调用时机一致,参数也一致。 |
三方应用ServiceAbility切换
Stage模型下三方应用不能对其他三方提供服务,应用可以根据具体业务选择切换方案。
业务类型 | 切换策略 |
对其他三方应用提供服务 | 需根据业务场景匹配到系统对应的场景化ExtensionAbility。 |
应用内:前台运行时公共使用 | 可以将该组件代码抽取成公共模块供其他组件使用。 |
应用内:进入后台时继续运行 | 可以将此服务切换为后台任务,可参考如下示例。 |
DataAbility切换
FA模型中的DataAbility对应Stage模型中的DataShareExtensionAbility。
与ServiceExtensionAbility类似,Stage模型下的DataShareExtensionAbility为系统API,只有系统应用才可以创建。因此,FA模型的DataAbility的切换,对于系统应用和三方应用策略有所不同。下面分别介绍这两种场景。
系统应用DataAbility切换至DataShareExtensionAbility
迁移步骤和PageAbility基本一致。
- 在Stage应用中创建DataShareExtensionAbility。
- 将FA应用中DataAbility的业务代码迁移到新创建的DataShareExtensionAbility中。 DataAbility和DataShareExtensionAbility生命周期对比见下表。
FA的DataAbility | Stage的DataShareExtensionAbility | 对比描述 |
onInitialized?(info: AbilityInfo): void | onCreate?(want: Want, callback: AsyncCallback<void>): void | 两者调用时机一致,函数名即入参都不一样,Stage模型下增加了入参want以便开发者在创建时获取参数。 |
update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void | update?(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket, callback: AsyncCallback<number>): void | 两者意义和调用时机一致,参数顺序和参数类型略有不同,需要简单改造。 |
query?(uri: string, columns: Array<string>, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<ResultSet>): void | query?(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: AsyncCallback<Object>): void; | 两者意义和调用时机一致,参数顺序和参数类型略有不同,需要简单改造。 |
delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void | delete?(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback<number>): | 两者意义和调用时机一致,参数类型略有不同,需要简单改造。 |
normalizeUri?(uri: string, callback: AsyncCallback<string>): void | normalizeUri?(uri: string, callback: AsyncCallback<string>): void | 两者意义和调用时机一致,参数也一致。 |
batchInsert?(uri: string, valueBuckets: Array<rdb.ValuesBucket>, callback: AsyncCallback<number>): void | batchInsert?(uri: string, values: Array<ValuesBucket>, callback: AsyncCallback<number>): void | 两者意义和调用时机一致,参数类型略有不同,需要简单改造。 |
denormalizeUri?(uri: string, callback: AsyncCallback<string>): void | denormalizeUri?(uri: string, callback: AsyncCallback<string>): void | 两者意义和调用时机一致,参数也一致。 |
insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback<number>): void | insert?(uri: string, value: ValuesBucket, callback: AsyncCallback<number>): void | 两者意义和调用时机一致,参数类型略有不同,需要简单改造。 |
openFile?(uri: string, mode: string, callback: AsyncCallback<number>): void | NA | Stage模型不支持uri跨进程访问,建议通过want携带FD和文件信息进行跨进程文件访问 |
getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback<Array<string>>): void | NA | Stage模型不支持uri跨进程访问,建议通过want携带FD和文件信息进行跨进程文件访问 |
getType?(uri: string, callback: AsyncCallback<string>): void | NA | Stage模型不支持uri跨进程访问,建议通过want携带FD和文件信息进行跨进程文件访问 |
executeBatch?(ops: Array<DataAbilityOperation>, callback: AsyncCallback<Array<DataAbilityResult>>): void | NA | DataShareExtensonAbility不提供该接口,开发者需根据业务功能重新实现。 |
call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback<PacMap>): void | NA | DataShareExtensonAbility不提供该接口,开发者需根据业务功能重新实现。 |
三方应用DataAbility改造为公共模块
Stage模型三方应用不能对其他三方提供数据,应用需要根据具体业务选择切换方案。
DataAbility业务类型 | 切换DataShareExtension策略 |
对三方提供数据 | 需根据业务场景匹配到系统对应的场景化ExtensionAbility。 |
应用内使用的数据 | 对应用内其他组件提供数据,建议提取公共模块。 |
卡片切换
卡片切换主要包含如下三部分:
- 卡片页面布局:FA模型卡片和Stage模型卡片的布局都采用类web范式开发可以直接复用。
- 卡片配置文件:FA模型的卡片配置在config.json中,Stage卡片配置在module.json5和form_config.json中(如下图1和图2)。
- 卡片业务逻辑:FA模型和Stage模型在卡片入口文件以及生命周期存在细微的差异(如下图3和图4)。
配置项 | FA模型 | Stage模型 |
配置项位置 | formAbility和forms配置都在config.json文件里 | 一级目录module.json5配置文件中配置extensionAbilities(针对formExtensionAbility的配置),二级目录form_config.json文件中配置forms(针对formExtensionAbility里包含的forms的详细配置) |
卡片代码路径 | srcPath,不带文件名 | srcEntrance,带文件名 |
语言 | srcLanguage支持配置为js或ets | 无此配置项,只支持ets |
是否使能卡片 | formsEnabled | 无,type配置项配置为form即使能 |
ability类型 | type:service | type:form |
二级目录配置标签 | 无 | metadata:包含name、value、resource。其中resource用于指向卡片二级目录form_config.json文件的位置 |
入口配置差异示意图1:
卡片信息配置差异示意图2:
入口及生命周期 | FA模型 | Stage模型 |
入口文件 | srcPath指向的目录下的form.ts | srcEntrance指向的文件 |
生命周期 | export default | import FormExtension from ‘@ohos.app.form.FormExtensionAbility’; export default class FormAbility extends FormExtension |
入口文件差异示意图3:
生命周期差异示意图4( 生命周期回调均一致,不需要调整):