鸿蒙App语法/结构/注意

注意

.1、权限申请使用流程

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/accesstoken-overview-0000001544703857-V3#ZH-CN_TOPIC_0000001574088913__%E6%9D%83%E9%99%90%E7%94%B3%E8%AF%B7%E4%BD%BF%E7%94%A8%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B

应用配置文件概述(Stage模型)

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/application-configuration-file-overview-stage-0000001428061460-V3
在基于Stage模型开发的应用项目代码下,都存在一个app.json5及一个或多个module.json5这两种配置文件。

app.json5主要包含以下内容:

  • 应用的全局配置信息,包含应用的包名、开发厂商、版本号等基本信息。
  • 特定设备类型的配置信息

module.json5主要包含以下内容:

  • Module的基本配置信息,例如Module名称、类型、描述、支持的设备类型等基本信息。
  • 应用组件信息,包含UIAbility组件和ExtensionAbility组件的描述信息。
  • 应用运行过程中所需的权限信息。

.1、app.json5配置文件

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/app-configuration-file-0000001427584584-V3

.1.1、bundleName—标识应用的Bundle名称,用于标识应用的唯一性(该标签不可缺省)

标签的值命名规则 :

  • 字符串以字母、数字、下划线和符号“.”组成。
  • 以字母开头。
  • 最小长度7个字节,最大长度127个字节。

推荐采用反域名形式命名(如com.example.demo,建议第一级为域名后缀com,第二级为厂商/个人名,第三级为应用名,也可以多级)。

.1.2、bundleType—标识应用的Bundle类型,用于区分应用或者原子化服务(该标签可以缺省,缺省为app)

该标签可选值为app和atomicService :

  • app:当前Bundle为普通应用。
  • atomicService:当前Bundle为元服务。

.1.3、debug—标识应用是否可调试,该标签由IDE编译构建时生成(该标签可以缺省,缺省为false)

  • true:可调试。
  • false:不可调试。

.1.4、icon—标识应用的图标,标签值为图标资源文件的索引(该标签不可缺省)

.1.5、label—标识应用的名称,标签值为字符串资源的索引(该标签不可缺省)

.1.6、description—标识应用的描述信息,标签值是字符串类型(最大255个字节)或对描述内容的字符串资源索引(该标签可以缺省,缺省为空)

.1.7、vendor—标识对应用开发厂商的描述。该标签的值是字符串类型(最大255个字节)(该标签可以缺省,缺省为空)

.1.8、versionCode—标识应用的版本号,该标签值为32位非负整数(该标签不可缺省)

此数字仅用于确定某个版本是否比另一个版本更新,数值越大表示版本越高。开发者可以将该值设置为任何正整数,但是必须确保应用的新版本都使用比旧版本更大的值。该标签不可缺省,versionCode值应小于2^31次方。

.1.9、versionName—标识应用版本号的文字描述,用于向用户展示(该标签不可缺省)

该标签仅由数字和点构成,推荐采用“A.B.C.D”四段式的形式。四段式推荐的含义如下所示。
第一段:主版本号/Major,范围0-99,重大修改的版本,如实现新的大功能或重大变化。
第二段:次版本号/Minor,范围0-99,表示实现较突出的特点,如新功能添加或大问题修复。
第三段:特性版本号/Feature,范围0-99,标识规划的新版本特性。
第四段:修订版本号/Patch,范围0-999,表示维护版本,修复bug。
标签最大字节长度为127。

.1.10、minCompatibleVersionCode—标识应用能够兼容的最低历史版本号,用于跨设备兼容性判断(该标签可缺省,缺省值等于versionCode标签值)

.1.11、minAPIVersion—标识应用运行需要的SDK的API最小版本(由build-profile.json5中的compatibleSdkVersion生成)

.1.12、targetAPIVersion—标识应用运行需要的API目标版本(由build-profile.json5中的compatibleSdkVersion生成)

.1.13、apiReleaseType—标识应用运行需要的API目标版本的类型,采用字符串类型表示(该标签可缺省,由IDE生成并覆盖)

取值为“CanaryN”、“BetaN”或者“Release”,其中,N代表大于零的整数。

  • Canary:受限发布的版本。
  • Beta:公开发布的Beta版本。
  • Release:公开发布的正式版本。

该字段由DevEco Studio读取当前使用的SDK的Stage来生成。

.1.14、multiProjects—标识当前工程是否支持多个工程的联合开发(可缺省,缺省值为false)

  • true:当前工程支持多个工程的联合开发。
  • false:当前工程不支持多个工程的联合开发。

多工程开发可以参考文档:多工程构建

.1.15、tablet—标识对tablet设备做的特殊配置,可以配置的属性字段有上文提到的:minAPIVersion、distributedNotificationEnabled(该标签可缺省,缺省时tablet设备使用app.json5公共区域配置的属性值)

如果使用该属性对tablet设备做了特殊配置,则应用在tablet设备中会采用此处配置的属性值,并忽略在app.json5公共区域配置的属性值

.1.16、tv—标识对tv设备做的特殊配置,可以配置的属性字段有上文提到的:minAPIVersion、distributedNotificationEnabled(该标签可缺省,缺省时tv设备使用app.json5公共区域配置的属性值)

如果使用该属性对tv设备做了特殊配置,则应用在tv设备中会采用此处配置的属性值,并忽略在app.json5公共区域配置的属性值。

.1.17、wearable—标识对wearable设备做的特殊配置,可以配置的属性字段有上文提到的:minAPIVersion、distributedNotificationEnabled(该标签可缺省,缺省时wearable设备使用app.json5公共区域配置的属性值)

如果使用该属性对wearable设备做了特殊配置,则应用在wearable设备中会采用此处配置的属性值,并忽略在app.json5公共区域配置的属性值。

.1.18、car—标识对car设备做的特殊配置,可以配置的属性字段有上文提到的:minAPIVersion、distributedNotificationEnabled(该标签可缺省,缺省时car设备使用app.json5公共区域配置的属性值)

如果使用该属性对car设备做了特殊配置,则应用在car设备中会采用此处配置的属性值,并忽略在app.json5公共区域配置的属性值。

.1.19、phone—标识对phone设备做的特殊配置,可以配置的属性字段有上文提到的:minAPIVersion、distributedNotificationEnabled(该标签可缺省,缺省时phone设备使用app.json5公共区域配置的属性值)

如果使用该属性对phone设备做了特殊配置,则应用在phone设备中会采用此处配置的属性值,并忽略在app.json5公共区域配置的属性值。

{
  "app": {
    "bundleName": "com.application.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:app_icon",
    "label": "$string:app_name",
    "description": "$string:description_application",
    "minAPIVersion": 9,
    "targetAPIVersion": 9,
    "apiReleaseType": "Release",
    "debug": false,
    "car": {
      "minAPIVersion": 8,
    }
  },
}

.2、module.json5配置文件

.2.1、name—标识当前Module的名称(该标签不可缺省)

标签值采用字符串表示(最大长度31个字节),该名称在整个应用要唯一,仅支持英文字符。

.2.2、type—标识当前Module的类型(该标签不可缺省)

类型有两种,分别:

  • entry:应用的主模块。
  • feature:应用的动态特性模块。

.2.3、srcEntry—标识当前Module所对应的代码路径(该标签可缺省,缺省值为空)

标签值为字符串(最长为127字节)

.2.4、description—标识当前Module的描述信息(该标签可缺省,缺省值为空)

标签值是字符串类型(最长255字节)或对描述内容的字符串资源索引。

.2.5、process—标识当前Module的进程名(可缺省,缺省为app.json5文件下app标签下的bundleName)

标签值为字符串类型(最长为31个字节)。如果在HAP标签下配置了process,该应用的所有UIAbility、DataShareExtensionAbility、ServiceExtensionAbility都运行在该进程中。

说明:

  • 仅支持系统应用配置,三方应用配置不生效。

.2.6、mainElement—标识当前Module的入口UIAbility名称或者ExtensionAbility名称(该标签可缺省,缺省值为空)

标签最大字节长度为255。

.2.7、deviceTypes—标识当前Module可以运行在哪类设备上(该标签不可缺省)

标签值采用字符串数组的表示。

.2.7.1、tablet—平板
.2.7.2、tv—智慧屏
.2.7.3、wearable—智能手表(系统能力较丰富的手表,具备电话功能)
.2.7.4、car—车机
.2.7.5、phone—手机

.2.8、deliveryWithInstall—标识当前Module是否在用户主动安装的时候安装(该标签不可缺省)

表示该Module对应的HAP是否跟随应用一起安装。

  • true:主动安装时安装。
  • false:主动安装时不安装。

.2.9、installationFree—标识当前Module是否支持免安装特性(该标签不可缺省)

  • true:表示支持免安装特性,且符合免安装约束。
  • false:表示不支持免安装特性。

说明:

  • 当应用的entry类型Module的该字段配置为true时,该应用的feature类型的该字段也需要配置为true。
  • 当应用的entry类型Module的该字段配置为false时,该应用的feature类型的该字段根据业务需求配置true或false。

.2.10、virtualMachine—标识当前Module运行的目标虚拟机类型,供云端分发使用,如应用市场和分发中心(该标签由IDE构建HAP的时候自动插入)

该标签值为字符串。如果目标虚拟机类型为ArkTS引擎,则其值为“ark+版本号”

.2.11、pages—标识当前Module的profile资源,用于列举每个页面信息(在有UIAbility的场景下,该标签不可缺省)

该标签最大长度为255个字节。该标签是一个profile文件资源,用于指定描述页面信息的配置文件。
在开发视图的resources/base/profile下面定义配置文件main_pages.json,其中文件名(main_pages)可自定义,需要和前文中pages标签指定的信息对应,配置文件中列举了当前应用组件中的页面信息。

.2.11.1、src—描述有关JavaScript模块中所有页面的路由信息,包括页面路径和页面名称。该值是一个字符串数组,其中每个元素表示一个页面(该标签不可缺省)
.2.11.2、window—用于定义与显示窗口相关的配置(该标签可缺省,缺省值为空)
.2.11.2.1、designWidth—标识页面设计基准宽度。以此为基准,根据实际设备宽度来缩放元素大小(可缺省,缺省值为720px)
.2.11.2.2、autoDesignWidth—标识页面设计基准宽度是否自动计算。当配置为true时,designWidth将会被忽略,设计基准宽度由设备宽度与屏幕密度计算得出(可缺省,缺省值为false)

.2.12、metadata—标识当前Module的自定义元信息,标签值为数组类型,只对当前Module、UIAbility、ExtensionAbility生效(该标签可缺省,缺省值为空)

.2.12.1、name—该标签标识数据项的键名称(该标签可缺省,缺省值为空)

字符串类型(最大长度255字节)

.2.12.2、value—该标签标识数据项的值(该标签可缺省,缺省值为空)

标签值为字符串(最大长度255字节)。

.2.13.2、resource—该标签标识定义用户自定义数据格式(该标签可缺省,缺省值为空)

标签值为标识该数据的资源的索引值。该标签最大字节长度为255字节。

.2.14、abilities—标识当前Module中UIAbility的配置信息,标签值为数组类型,只对当前UIAbility生效(该标签可缺省,缺省值为空)

abilities标签描述UIAbility组件的配置信息,标签值为数组类型,该标签下的配置只对当前UIAbility生效。

.2.14.1、name—标识当前UIAbility组件的名称(该标签不可缺省)

该名称在整个应用要唯一,标签值采用字符串表示(最大长度127个字节),仅支持英文字符。

.2.14.2、srcEntry—该标签标识入口UIAbility的代码路径(该标签不可缺省)

标签值为字符串(最长为127字节)

.2.14.3、launchType—标识当前UIAbility组件的启动模式(可缺省,该标签缺省为“singleton”)

可选标签值:

  • multiton:多实例模式,每次启动创建一个新的实例。
  • singleton:单实例模式,仅第一次启动创建新实例。
  • specified:指定实例模式,运行时由开发者决定是否创建新实例。
.2.14.4、description—标识当前UIAbility组件的描述信息(该标签可缺省,缺省值为空)

标签值是字符串类型(最长255字节)或对描述内容的资源索引,要求采用资源索引方式,以支持多语言。

.2.14.5、icon—标识当前UIAbility组件的图标(该标签可缺省,缺省值为空。如果UIAbility被配置为MainElement,该标签必须配置)

标签值为图标资源文件的索引。

.2.14.6、label—标识当前UIAbility组件对用户显示的名称(该标签不可缺省)

标签值配置为该名称的资源索引以支持多语言。
如果UIAbility被配置当前Module的mainElement时,该标签必须配置,且应用内唯一。

.2.14.7、permissions—标识当前UIAbility组件自定义的权限信息(该标签可缺省,缺省值为空)

当其他应用访问该UIAbility时,需要申请相应的权限信息。
一个数组元素为一个权限名称。通常采用反向域名格式(最大255字节),取值为系统预定义的权限。

.2.14.8、metadata—标识当前UIAbility组件的元信息(该标签可缺省,缺省值为空)
.2.14.9、exported—标识当前UIAbility组件是否可以被其他应用调用(该标签可缺省,缺省值为false)
  • true:表示可以被其他应用调用。
  • false:表示不可以被其他应用调用。
.2.14.10、continuable—标识当前UIAbility组件是否可以迁移(该标签可缺省,缺省值为空)
  • true:表示可以被迁移。
  • false:表示不可以被迁移。
.2.14.11、skills—标识当前UIAbility组件或ExtensionAbility组件能够接收的Want的特征集,为数组格式(该标签可缺省,缺省值为空)

配置规则:

  • 对于Entry类型的HAP,应用可以配置多个具有入口能力的skills标签(即配置了ohos.want.action.home和entity.system.home)。
  • 对于Feature类型的HAP,只有应用可以配置具有入口能力的skills标签,服务不允许配置。
.2.14.11.1、actions—标识能够接收的Want的Action值的集合,取值通常为系统预定义的action值,也允许自定义(可缺省,缺省值为空)
.2.14.11.2、entities—标识能够接收Want的Entity值的集合(可缺省,缺省值为空)
.2.14.11.3、uris—标识与Want中URI(Uniform Resource Identifier)相匹配的集合可缺省,缺省值为空)
.2.14.11.4、scheme—标识URI的协议名部分,常见的有http、https、file、ftp等(uris中仅配置type时可以缺省,缺省值为空,否则不可缺省)
.2.14.11.5、host—标识URI的主机地址部分,该字段要在schema存在时才有意义(可缺省,缺省值为空)

常见的方式:

  • 域名方式,如example.com。
  • IP地址方式,如10.10.10.1。
.2.14.11.6、port—标识URI的端口部分(可缺省,缺省值为空)

如http默认端口为80,https默认端口是443,ftp默认端口是21。该字段要在schema和host都存在时才有意义。

.2.14.11.7、path | pathStartWith | pathRegex—标识URI的路径部分,path、pathStartWith和pathRegex配置时三选一(可缺省,缺省值为空)

path标识URI与want中的路径部分全匹配,pathStartWith标识URI与want中的路径部分允许前缀匹配,pathRegex标识URI与want中的路径部分允许正则匹配。该字段要在schema和host都存在时才有意义。

.2.14.11.8、type—标识与Want相匹配的数据类型(可缺省,缺省值为空)

使用MIME(Multipurpose Internet Mail Extensions)类型规范。可与schema同时配置,也可以单独配置。

.2.14.12、backgroundModes—标识当前UIAbility组件的长时任务集合(该标签可缺省,缺省值为空)

指定用于满足特定类型的长时任务。

长时任务类型有如下:

  • dataTransfer:通过网络/对端设备进行数据下载、备份、分享、传输等业务。
  • audioPlayback:音频输出业务。
  • audioRecording:音频输入业务。
  • location:定位、导航业务。
  • bluetoothInteraction:蓝牙扫描、连接、传输业务(穿戴)。
  • multiDeviceConnection:多设备互联业务。
  • wifiInteraction:Wi-Fi扫描、连接、传输业务(克隆多屏)。
  • voip:音视频电话,VoIP业务。
  • taskKeeping:计算业务。
.2.14.13、startWindowIcon—标识当前UIAbility组件启动页面图标资源文件的索引(不可缺省)

取值示例:$media:icon。该标签最大字节长度为255

.2.14.14、startWindowBackground—标识当前UIAbility组件启动页面背景颜色资源文件的索引(不可缺省)

取值示例:$color:red。该标签最大字节长度为255

.2.14.15、removeMissionAfterTerminate—标识当前UIAbility组件销毁后是否从任务列表中移除任务(该标签可缺省,缺省值为false)

为布尔类型:

  • true表示销毁后移除任务。
  • false表示销毁后不移除任务
.2.14.15、orientation—标识当前UIAbility组件启动时的方向(该标签可缺省,缺省值为unspecified)

该方向的取值范围包括:

  • unspecified:未指定方向,由系统自动判断显示方向。
  • landscape:横屏。
  • portrait:竖屏。
  • landscape_inverted:反向横屏。
  • portrait_inverted:反向竖屏。
  • auto_rotation:随传感器旋转。
  • auto_rotation_landscape:传感器横屏旋转,包括了横屏和反向横屏。
  • auto_rotation_portrait:传感器竖屏旋转,包括了竖屏和反向竖屏。
  • auto_rotation_restricted:传感器开关打开,方向可随传感器旋转。
  • auto_rotation_landscape_restricted:传感器开关打开,方向可随传感器旋转为横屏, 包括了横屏和反向横屏。
  • auto_rotation_portrait_restricted:传感器开关打开,方向随可传感器旋转为竖屏, 包括了竖屏和反向竖屏。
  • locked:传感器开关关闭,方向锁定。
.2.14.16、supportWindowMode—标识当前UIAbility组件所支持的窗口模式(该标签可缺省,缺省值为[“fullscreen”, “split”, “floating”])

包含:

  • fullscreen:全屏模式。
  • split:分屏模式。
  • floating:悬浮窗模式。
.2.14.17、priority—标识当前UIAbility组件的优先级,仅支持系统应用配置,三方应用配置不生效(该标签可缺省,缺省值为0)

隐式查询时,优先级越高,UIAbility在返回列表越靠前。该标签取值为integer类型,取值范围0-10。数值越大,优先级越高

.2.14.18、maxWindowRatio—标识当前UIAbility组件支持的最大的宽高比(该标签可缺省,缺省值为平台支持的最大的宽高比)

该标签最小取值为0。

.2.14.19、minWindowRatio—标识当前UIAbility组件支持的最小的宽高比(该标签可缺省,缺省值为平台支持的最小的宽高比)

该标签最小取值为0

.2.14.20、maxWindowWidth—标识当前UIAbility组件支持的最大的窗口宽度,宽度单位为vp(该标签可缺省,缺省值为平台支持的最大的窗口宽度)

该标签最小取值为0。

.2.14.21、minWindowWidth—标识当前UIAbility组件支持的最小的窗口宽度, 宽度单位为vp(该标签可缺省,缺省值为平台支持的最小的窗口宽度)

该标签最小取值为0

.2.14.22、maxWindowHeight—标识当前UIAbility组件支持的最大的窗口高度, 高度单位为vp(该标签可缺省,缺省值为平台支持的最大的窗口高度)

该标签最小取值为0

.2.14.23、minWindowHeight—标识当前UIAbility组件支持的最小的窗口高度, 高度单位为vp(该标签可缺省,缺省值为平台支持的最小的窗口高度)

该标签最小取值为0

.2.14.24、excludeFromMissions—标识当前UIAbility组件是否在最近任务列表中显示(该标签可缺省,缺省值为false)
  • true:表示不在任务列表中显示。
  • false:表示在任务列表中显示。

说明:

  • 仅支持系统应用配置,三方应用配置不生效。

.2.15、extensionAbilities—标识当前Module中ExtensionAbility的配置信息,标签值为数组类型,只对当前ExtensionAbility生效(该标签可缺省,缺省值为空)

.2.15.1、name—标识当前ExtensionAbility组件的名称(该标签不可缺省)

标签值最大长度为127个字节,该名称在整个应用要唯一。

.2.15.2、srcEntry—标识当前ExtensionAbility组件所对应的代码路径(该标签不可缺省)

标签值最大长度为127字节

.2.15.3、description—标识当前ExtensionAbility组件的描述(该标签可缺省,缺省值为空)

标签值最大长度为255字节,标签也可以是描述内容的资源索引,用于支持多语言。

.2.15.4、icon—标识当前ExtensionAbility组件的图标(该标签可缺省,缺省值为空)

标签值为资源文件的索引。如果ExtensionAbility组件被配置为MainElement,该标签必须配置。

.2.15.5、label—标识当前ExtensionAbility组件对用户显示的名称(该标签不可缺省)

标签值配置为该名称的资源索引以支持多语言。
说明:

  • 如果ExtensionAbility被配置当前Module的mainElement时,该标签必须配置,且应用内唯一。
.2.15.6、type—标识当前ExtensionAbility组件的类型(该标签不可缺省)

取值为:

  • form:卡片的ExtensionAbility。
  • workScheduler:延时任务的ExtensionAbility。
  • inputMethod:输入法的ExtensionAbility。
  • service:后台运行的service组件。
  • accessibility:辅助能力的ExtensionAbility。
  • dataShare:数据共享的ExtensionAbility。
  • fileShare:文件共享的ExtensionAbility。
  • staticSubscriber:静态广播的ExtensionAbility。
  • wallpaper:壁纸的ExtensionAbility。
  • backup:数据备份的ExtensionAbility。
  • window:该ExtensionAbility会在启动过程中创建一个window,为开发者提供界面开发。开发者开发出来的界面将通过abilityComponent控件组合到其他应用的窗口中。
  • thumbnail:获取文件缩略图的ExtensionAbility,开发者可以对自定义文件类型的文件提供缩略。
  • preview:该ExtensionAbility会将文件解析后在一个窗口中显示,开发者可以通过将此窗口组合到其他应用窗口中。

说明:

  • 其中service和dataShare类型,仅支持系统应用配置,三方应用配置不生效。
.2.15.7、permissions—标识当前ExtensionAbility组件自定义的权限信息(该标签可缺省,缺省值为空)

当其他应用访问该ExtensionAbility时,需要申请相应的权限信息。

一个数组元素为一个权限名称。通常采用反向域名格式(最大255字节),可以是系统预定义的权限,也可以是该应用自定义的权限。如果是后者,需与defPermissions标签中定义的某个权限的name标签值一致。

.2.15.8、uri—标识当前ExtensionAbility组件提供的数据URI(该标签可缺省,缺省值为空)

为字符数组类型(最大长度255),用反向域名的格式表示。

说明:

  • 该标签在type为dataShare类型的ExtensionAbility时,不可缺省。
.2.15.9、skills—标识当前ExtensionAbility组件能够接收的Want的特征集,为数组格式(该标签可缺省,缺省值为空)

配置规则:entry包可以配置多个具有入口能力的skills标签(配置了ohos.want.action.home和entity.system.home)的ExtensionAbility,其中第一个配置了skills标签的ExtensionAbility中的label和icon作为应用或服务的label和icon。

说明:

  • 应用的Feature包可以配置具有入口能力的skills标签。
  • 服务的Feature包不能配置具有入口能力的skills标签。
.2.15.10、metadata—标识当前ExtensionAbility组件的元信息(该标签可缺省,缺省值为空)
.2.15.11、exported—标识当前ExtensionAbility组件是否可以被其他应用调用(该标签可缺省,缺省值为false)

为布尔类型。

  • true:表示可以被其他应用调用。
  • false:表示不可以被其他应用调用。

.2.16、requestPermissions—标识当前应用运行时需向系统申请的权限集合(该标签可缺省,缺省值为空)

.2.16.1、name—必须,填写需要使用的权限名称
.2.16.2、reason—可选,当申请的权限为user_grant权限时此字段必填,用于描述申请权限的原因

说明:

  • 当申请的权限为user_grant权限时,如果未填写该字段则不允许在应用市场上架,并且需要进行多语种适配。
.2.16.3、usedScene—可选,当申请的权限为user_grant权限时此字段必填(abilities:空。when:空。)

描述权限使用的场景由abilities和when组成。其中abilities可以配置为多个UIAbility组件,when表示调用时机。

说明:

  • 默认为可选,当申请的权限为user_grant权限时,abilities标签必填,when标签可选。

.2.17、testRunner—标识当前Module用于支持对测试框架的配置(该标签可缺省,缺省值为空)

.2.17.1、name—标识测试框架对象名称(不可缺省)

该标签最大字节长度为255个字节。

.2.17.2、srcPath—标识测试框架代码路径(不可缺省)

该标签最大字节长度为255个字节。

.2.18、shortcuts—标识应用的快捷方式信息

标签值为数组,最多可以配置四个快捷方式。其包含四个子标签shortcutId、label、icon、wants。

.2.18.1、shortcutId—标识快捷方式的ID。字符串的最大长度为63字节(该标签不可缺省)
.2.18.2、label—标识快捷方式的标签信息,即快捷方式对外显示的文字描述信息(该标签可缺省,缺省值为空)

取值可以是描述性内容,也可以是标识label的资源索引。字符串最大长度为255字节。

.2.18.3、icon—标识快捷方式的图标,标签值为资源文件的索引(该标签可缺省,缺省值为空)
.2.18.4、wants—标识快捷方式内定义的目标wants信息集合(该标签可缺省,缺省为空)

每个wants可配置bundleName和abilityName两个子标签。

  • bundleName:表示快捷方式的目标Bundle名称,字符串类型。
  • abilityName:表示快捷方式的目标组件名,字符串类型。

.2.19、distroFilter—该标签下的子标签均为可选字段,在应用市场云端分发时使用

distroFilter标签用于定义HAP对应的细分设备规格的分发策略,以便在应用市场进行云端分发应用包时做精准匹配。该标签可配置的分发策略维度包括API Version、屏幕形状、屏幕尺寸、屏幕分辨率,设备的国家与地区码。在进行分发时,通过deviceType与这五个属性的匹配关系,唯一确定一个用于分发到设备的HAP。

该标签需要配置在/resource/profile资源目录下,并在模块的metadata的resource字段中引用。

.2.19.1、apiVersion—标识支持的apiVersion范围(该标签可缺省,缺省值为空)
.2.19.2、screenShape—标识屏幕形状的支持策略(该标签可缺省,缺省值为空)
.2.19.2.1、policy—标识该子属性取值规则(该标签不可缺省)

配置为“exclude”或“include”。

  • exclude:表示需要排除的value属性。
  • include:表示需要包含的value属性。
.2.19.2.2、value—支持的取值为circle(圆形)、rect(矩形)(该标签不可缺省)

场景示例:针对智能穿戴设备,可为圆形表盘和矩形表盘分别提供不同的HAP。

.2.19.3、screenWindow—标识应用运行时窗口的分辨率支持策略(该标签可缺省,缺省值为空)

该字段仅支持对轻量级智能穿戴设备进行配置。

.2.19.3.1、policy—标识该子属性取值规则(该标签不可缺省)

配置为“exclude”或“include”。

  • exclude:表示该字段取值不包含value枚举值匹配规则的匹配该属性。
  • include:表示该字段取值满足value枚举值匹配规则的匹配该属性。
.2.19.3.2、value—单个字符串的取值格式为“宽 * 高”(该标签不可缺省)

取值为整数像素值,例如“454 * 454”。

.2.19.4、screenDensity—标识屏幕的像素密度(dpi:Dot Per Inch)(该标签可缺省,缺省值为空)
.2.19.4.1、policy—标识该子属性取值规则(该标签不可缺省)

配置为“exclude”或“include”。

  • exclude:表示需要排除的value属性。
  • include:表示需要包含的value属性。
.2.19.4.2、value—该标签标识屏幕的像素密度(dpi :Dot Per Inch)(该标签不可缺省)

该标签为字符串数组,字符串范围如下。

  • sdpi:表示小规模的屏幕密度(Small-scale Dots per Inch),适用于dpi取值为(0,120]的设备。
  • mdpi:表示中规模的屏幕密度(Medium-scale Dots Per Inch),适用于dpi取值为(120,160]的设备。
  • ldpi:表示大规模的屏幕密度(Large-scale Dots Per Inch),适用于dpi取值为(160,240]的设备。
  • xldpi:表示大规模的屏幕密度(Extra Large-scale Dots Per Inch),适用于dpi取值为(240,320]的设备。
  • xxldpi:表示大规模的屏幕密度(Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(320,480]的设备。
  • xxxldpi:表示大规模的屏幕密度(Extra Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(480, 640]的设备。
.2.19.5、countryCode—表示应用需要分发的国家地区码(该标签可缺省,缺省值为空)

具体值以ISO-3166-1标准为准。支持多个国家和地区枚举定义。

.2.19.5.1、policy—标识该子属性取值规则(该标签不可缺省)

配置为“exclude”或“include”。

  • exclude:表示需要排除的value属性。
  • include:表示需要包含的value属性。
.2.19.5.2、value—标识应用需要分发的国家地区码(该标签不可缺省)

取值为整数像素值,例如“454 * 454”。

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "tv",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "virtualMachine": "ark",
    "metadata": [
      {
        "name": "string",
        "value": "string",
        "resource": "$profile:distributionFilter_config"
      }
    ],
    "abilities": [
      {
         "name": "EntryAbility",
    "srcEntry": "./ets/entryability/EntryAbility.ts",
    "launchType":"singleton",
    "description": "$string:description_main_ability",
    "icon": "$media:icon",
    "label": "Login",
    "permissions": [],
    "metadata": [],
    "exported": true,
    "continuable": true,
    "skills": [{
          "actions": [
            "ohos.want.action.home"
          ],
          "entities": [
            "entity.system.home"
          ],
          "uris": [
            {
              "scheme":"http",
              "host":"example.com",
              "port":"80",
              "path":"path",
              "type": "text/*"
            }
          ]
        }],
    "backgroundModes": [
      "dataTransfer",
      "audioPlayback",
      "audioRecording",
      "location",
      "bluetoothInteraction",
      "multiDeviceConnection",
      "wifiInteraction",
      "voip",
      "taskKeeping"
    ],
    "startWindowIcon": "$media:icon",
    "startWindowBackground": "$color:red",
    "removeMissionAfterTerminate": true,
    "orientation": " ",
    "supportWindowMode": ["fullscreen", "split", "floating"],
    "maxWindowRatio": 3.5,
    "minWindowRatio": 0.5,
    "maxWindowWidth": 2560,
    "minWindowWidth": 1400,
    "maxWindowHeight": 300,
    "minWindowHeight": 200,
    "excludeFromMissions": false
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.abilitydemo.permission.PROVIDER",
        "reason": "$string:reason",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when": "inuse"
        }
      }
    ],
    "extensionAbilities": [
    {
      "name": "FormName",
      "srcEntry": "./form/MyForm.ts",
      "icon": "$media:icon",
      "label" : "$string:extension_name",
      "description": "$string:form_description",
      "type": "form", 
      "permissions": ["ohos.abilitydemo.permission.PROVIDER"],
      "readPermission": "",
      "writePermission": "",
      "exported": true,
      "uri":"scheme://authority/path/query",
      "skills": [{
        "actions": [],
        "entities": [],
        "uris": []
      }],
      "metadata": [
        {
          "name": "ohos.extension.form",
          "resource": "$profile:form_config", 
        }
      ]
    }
  ],
  "shortcuts": [
    {
      "shortcutId": "id_test1",
      "label": "$string:shortcut",
      "icon": "$media:aa_icon",
      "wants": [
        {
          "bundleName": "com.ohos.hello",
          "abilityName": "EntryAbility"
        }
      ]
    }
  ],
  "distroFilter": {
    "screenShape": {
      "policy": "include",
      "value": [
        "circle",
        "rect"
      ]
    },
    "screenWindow": {
      "policy": "include",
      "value": [
        "454*454",
        "466*466"
      ]
    },
    "screenDensity": {
      "policy": "exclude",
      "value": [
        "ldpi",
        "xldpi"
      ]
    },
    "countryCode": { // 支持中国和香港地区分发
      "policy": "include",
      "value": [
        "CN",
        "HK"
      ]
    }
  },
  "testRunner": {
      "name": "myTestRunnerName",
      "srcPath": "etc/test/TestRunner.ts"
    }
  }
}

语法

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。因此,在学习ArkTS语言之前,建议开发者具备TS语言开发能力。

当前,ArkTS在TS的基础上主要扩展了如下能力:

  • 基本语法:ArkTS定义了声明式UI描述、自定义组件和动态扩展UI元素的能力,再配合ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共同构成了UI开发的主体。
  • 状态管理:ArkTS提供了多维度的状态管理机制。在UI开发框架中,与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递。开发者可以灵活地利用这些能力来实现数据和UI的联动。
  • 渲染控制:ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

.1、基本语法概述

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-basic-syntax-overview-0000001531611153-V3

  • 装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如上述示例中@Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,状态变量变化会触发UI刷新。
  • UI描述:以声明式的方式来描述UI的结构,例如build()方法中的代码块。
  • 自定义组件:可复用的UI单元,可组合其他组件,如上述被@Component装饰的struct Hello。
  • 系统组件:ArkUI框架中默认内置的基础和容器组件,可直接被开发者调用,比如示例中的Column、Text、Divider、Button。
  • 属性方法:组件可以通过链式调用配置多项属性,如fontSize()、width()、height()、backgroundColor()等。
  • 事件方法:组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick()。
  • 系统组件、属性方法、事件方法具体使用可参考基于ArkTS的声明式开发范式。

除此之外,ArkTS扩展了多种语法范式来使开发更加便捷:

  • @Builder/@BuilderParam:特殊的封装UI描述的方法,细粒度的封装和复用UI描述。
  • @Extend/@Styles:扩展内置组件和封装属性样式,更灵活地组合内置组件。
    stateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式。
    在这里插入图片描述

.2、声明式UI描述

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-declarative-ui-description-0000001524416537-V3
ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。

.2.1、创建组件

//无参数
Column() {
  Text('item 1')
  Divider()
  Text('item 2')
}
// string类型的参数
Text('test')
// $r形式引入应用资源,可应用于多语言场景
Text($r('app.string.title_value'))
// 无参数形式
Text()
Image(this.imagePath)
Image('https://' + this.imageUrl)
Text(`count: ${this.count}`)

.2.2、配置属性

属性方法以“.”链式调用的方式配置系统组件的样式和其他属性,建议每个属性方法单独写一行。

Text('hello')
  .fontSize(this.size)
Image('test.jpg')
  .width(this.count % 2 === 0 ? 100 : 200)    
  .height(this.offset + 100)

.2.3、配置事件

//使用箭头函数配置组件的事件方法。
Button('Click me')
  .onClick(() => {
    this.myText = 'ArkUI';
  })
//使用匿名函数表达式配置组件的事件方法,要求使用bind,以确保函数体中的this指向当前组件。
Button('add counter')
  .onClick(function(){
    this.counter += 2;
  }.bind(this))
//使用组件的成员函数配置组件的事件方法。
myClickHandler(): void {
  this.counter += 2;
}
...
Button('add counter')
  .onClick(this.myClickHandler.bind(this))
//使用声明的箭头函数,可以直接调用,不需要bind this
fn = () => {
  console.info(`counter: ${this.counter}`)
  this.counter++
}
...
Button('add counter')
  .onClick(this.fn)

.2.4、配置子组件

如果组件支持子组件配置,则需在尾随闭包"{…}"中为组件添加子组件的UI描述。Column、Row、Stack、Grid、List等组件都是容器组件。

//以下是简单的Column组件配置子组件的示例。
Column() {
  Text('Hello')
    .fontSize(100)
  Divider()
  Text(this.myText)
    .fontSize(100)
    .fontColor(Color.Red)
}
//容器组件均支持子组件配置,可以实现相对复杂的多级嵌套。
Column() {
  Row() {
    Image('test1.jpg')
      .width(100)
      .height(100)
    Button('click +1')
      .onClick(() => {
        console.info('+1 clicked!');
      })
  }
}

.3、自定义组件

.3.1、创建自定义组件

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-create-custom-components-0000001473537046-V3
在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。因此,将UI和部分业务逻辑封装成自定义组件是不可或缺的能力。

自定义组件具有以下特点:

  • 可组合:允许开发者组合使用系统组件、及其属性和方法。
  • 可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用。
  • 数据驱动UI更新:通过状态变量的改变,来驱动UI的刷新。
.3.1.1、自定义组件的基本用法

如果在另外的文件中引用该自定义组件,需要使用export关键字导出,并在使用的页面import该自定义组件。

@Component
struct HelloComponent {
  @State message: string = 'Hello, World!';

  build() {
    // HelloComponent自定义组件组合系统组件Row和Text
    Row() {
      Text(this.message)
        .onClick(() => {
          // 状态变量message的改变驱动UI刷新,UI从'Hello, World!'刷新为'Hello, ArkUI!'
          this.message = 'Hello, ArkUI!';
        })
    }
  }
}
.3.1.2、自定义组件的基本结构
  • struct:自定义组件基于struct实现,struct + 自定义组件名 + {…}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。
  • @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。
  • build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。
  • @Entry:@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。@Entry可以接受一个可选的LocalStorage的参数。
.3.1.3、成员函数/变量

自定义组件除了必须要实现build()函数外,还可以实现其他成员函数,成员函数具有以下约束:

  • 不支持静态函数。
  • 成员函数的访问是私有的。

自定义组件可以包含成员变量,成员变量具有以下约束:

  • 不支持静态成员变量。
  • 所有成员变量都是私有的,变量的访问规则与成员函数的访问规则相同。
  • 自定义组件的成员变量本地初始化有些是可选的,有些是必选的。具体是否需要本地初始化,是否需要从父组件通过参数传递初始化子组件的成员变量,请参考状态管理。
.3.1.4、build()函数

所有声明在build()函数的语言,我们统称为UI描述,UI描述需要遵循以下规则:

  • @Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。
    @Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。
@Entry
@Component
struct MyComponent {
  build() {
    // 根节点唯一且必要,必须为容器组件
    Row() {
      ChildComponent() 
    }
  }
}

@Component
struct ChildComponent {
  build() {
    // 根节点唯一且必要,可为非容器组件
    Image('test.jpg')
  }
}
  • 不允许声明本地变量,反例如下。
build() {
  // 反例:不允许声明本地变量
  let a: number = 1;
}
  • 不允许在UI描述里直接使用console.info,但允许在方法或者函数里使用,反例如下
build() {
  // 反例:不允许console.info
  console.info('print debug log');
}
  • 不允许创建本地的作用域,反例如下
build() {
  // 反例:不允许本地作用域
  {
    ...
  }
}
  • 不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值
@Component
struct ParentComponent {
  doSomeCalculations() {
  }

  calcTextValue(): string {
    return 'Hello World';
  }

  @Builder doSomeRender() {
    Text(`Hello World`)
  }

  build() {
    Column() {
      // 反例:不能调用没有用@Builder装饰的方法
      this.doSomeCalculations();
      // 正例:可以调用
      this.doSomeRender();
      // 正例:参数可以为调用TS方法的返回值
      Text(this.calcTextValue())
    }
  }
}
  • 不允许switch语法,如果需要使用条件判断,请使用if。反例如下
build() {
  Column() {
    // 反例:不允许使用switch语法
    switch (expression) {
      case 1:
        Text('...')
        break;
      case 2:
        Image('...')
        break;
      default:
        Text('...')
        break;
    }
  }
}
  • 不允许使用表达式,反例如下
build() {
  Column() {
    // 反例:不允许使用表达式
    (this.aVar > 10) ? Text('...') : Image('...')
  }
}
.3.1.5、自定义组件通用样式

自定义组件通过“.”链式调用的形式设置通用样式。

ArkUI给自定义组件设置样式时,相当于给MyComponent2套了一个不可见的容器组件,而这些样式是设置在容器组件上的,而非直接设置给MyComponent2的Button组件。通过渲染结果我们可以很清楚的看到,背景颜色红色并没有直接生效在Button上,而是生效在Button所处的开发者不可见的容器组件上。

@Component
struct MyComponent2 {
  build() {
    Button(`Hello World`)
  }
}

@Entry
@Component
struct MyComponent {
  build() {
    Row() {
      MyComponent2()
        .width(200)
        .height(300)
        .backgroundColor(Color.Red)
    }
  }
}

.3.2、页面和自定义组件生命周期

在开始之前,我们先明确自定义组件和页面的关系:

  • 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
  • 页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。
    在这里插入图片描述

.4、注解相关

.4.1、@Builder装饰器:自定义构建函数

前面章节介绍了如何创建一个自定义组件。该自定义组件内部UI结构固定,仅与使用方进行数据传递。ArkUI还提供了一种更轻量的UI元素复用机制@Builder,@Builder所装饰的函数遵循build()函数语法规则,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。

为了简化语言,我们将@Builder装饰的函数也称为“自定义构建函数”。‘

  • 允许在自定义组件内定义一个或多个@Builder方法,该方法被认为是该组件的私有、特殊类型的成员函数。
  • 自定义构建函数可以在所属组件的build方法和其他自定义构建函数中调用,但不允许在组件外调用。
  • 在自定义函数体中,this指代当前所属组件,组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递。
  • 全局的自定义构建函数可以被整个应用获取,不允许使用this和bind方法。
  • 如果不涉及组件状态变化,建议使用全局的自定义构建方法。
.4.1.1、参数传递规则

自定义构建函数的参数传递有按值传递和按引用传递两种,均需遵守以下规则:

  • 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
  • 在自定义构建函数内部,不允许改变参数值。如果需要改变参数值,且同步回调用点,建议使用@Link。
  • @Builder内UI语法遵循UI语法规则。
  • 只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递。
.4.1.1.1、按引用传递参数

按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。ArkUI提供$$作为按引用传递参数的范式。

ABuilder( $$ : { paramA1: string, paramB1 : string } );
@Builder function ABuilder($$: { paramA1: string }) {
  Row() {
    Text(`UseStateVarByReference: ${$$.paramA1} `)
  }
}
@Entry
@Component
struct Parent {
  @State label: string = 'Hello';
  build() {
    Column() {
      // 在Parent组件中调用ABuilder的时候,将this.label引用传递给ABuilder
      ABuilder({ paramA1: this.label })
      Button('Click me').onClick(() => {
        // 点击“Click me”后,UI从“Hello”刷新为“ArkUI”
        this.label = 'ArkUI';
      })
    }
  }
}
4.1.1.2、按值传递参数

调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。

@Builder function ABuilder(paramA1: string) {
  Row() {
    Text(`UseStateVarByValue: ${paramA1} `)
  }
}
@Entry
@Component
struct Parent {
  @State label: string = 'Hello';
  build() {
    Column() {
      ABuilder(this.label)
    }
  }
}

.4.2、@BuilderParam装饰器:引用@Builder函数

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-builderparam-0000001524416541-V3
当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,类似slot占位符。

  • @BuilderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化。
///使用所属自定义组件的自定义构建函数或者全局的自定义构建函数,在本地初始化@BuilderParam。
@Builder function GlobalBuilder0() {}

@Component
struct Child {
  @Builder doNothingBuilder() {};

  @BuilderParam aBuilder0: () => void = this.doNothingBuilder;
  @BuilderParam aBuilder1: () => void = GlobalBuilder0;
  build(){}
}


///用父组件自定义构建函数初始化子组件@BuilderParam装饰的方法。
@Component
struct Child {
  @BuilderParam aBuilder0: () => void;

  build() {
    Column() {
      this.aBuilder0()
    }
  }
}

@Entry
@Component
struct Parent {
  @Builder componentBuilder() {
    Text(`Parent builder `)
  }

  build() {
    Column() {
      Child({ aBuilder0: this.componentBuilder })
    }
  }
}

///以下示例中,Parent组件在调用this.componentBuilder()时,this指向其所属组件,即“Parent”。@Builder componentBuilder()传给子组件@BuilderParam aBuilder0,在Child组件中调用this.aBuilder0()时,this指向在Child的label,即“Child”。
@Component
struct Child {
  label: string = `Child`
  @BuilderParam aBuilder0: () => void;

  build() {
    Column() {
      this.aBuilder0()
    }
  }
}

@Entry
@Component
struct Parent {
  label: string = `Parent`

  @Builder componentBuilder() {
    Text(`${this.label}`)
  }

  build() {
    Column() {
      this.componentBuilder()
      Child({ aBuilder0: this.componentBuilder })
    }
  }
}

  • @BuilderParam装饰的方法可以是有参数和无参数的两种形式,需与指向的@Builder方法类型匹配。@BuilderParam装饰的方法类型需要和@Builder方法类型一致。
@Builder function GlobalBuilder1($$ : {label: string }) {
  Text($$.label)
    .width(400)
    .height(50)
    .backgroundColor(Color.Green)
}

@Component
struct Child {
  label: string = 'Child'
  // 无参数类,指向的componentBuilder也是无参数类型
  @BuilderParam aBuilder0: () => void;
  // 有参数类型,指向的GlobalBuilder1也是有参数类型的方法
  @BuilderParam aBuilder1: ($$ : { label : string}) => void;

  build() {
    Column() {
      this.aBuilder0()
      this.aBuilder1({label: 'global Builder label' } )
    }
  }
}

@Entry
@Component
struct Parent {
  label: string = 'Parent'

  @Builder componentBuilder() {
    Text(`${this.label}`)
  }

  build() {
    Column() {
      this.componentBuilder()
      Child({ aBuilder0: this.componentBuilder, aBuilder1: GlobalBuilder1 })
    }
  }
}
  • 在自定义组件中使用@BuilderParam装饰的属性时也可通过尾随闭包进行初始化。在初始化自定义组件时,组件后紧跟一个大括号“{}”形成尾随闭包场景。
// xxx.ets
@Component
struct CustomContainer {
  @Prop header: string;
  @BuilderParam closer: () => void

  build() {
    Column() {
      Text(this.header)
        .fontSize(30)
      this.closer()
    }
  }
}

@Builder function specificParam(label1: string, label2: string) {
  Column() {
    Text(label1)
      .fontSize(30)
    Text(label2)
      .fontSize(30)
  }
}

@Entry
@Component
struct CustomContainerUser {
  @State text: string = 'header';

  build() {
    Column() {
      // 创建CustomContainer,在创建CustomContainer时,通过其后紧跟一个大括号“{}”形成尾随闭包
      // 作为传递给子组件CustomContainer @BuilderParam closer: () => void的参数
      CustomContainer({ header: this.text }) {
        Column() {
          specificParam('testA', 'testB')
        }.backgroundColor(Color.Yellow)
        .onClick(() => {
          this.text = 'changeHeader';
        })
      }
    }
  }
}

.4.3、@Styles装饰器:定义组件重用样式

@Styles装饰器可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用。通过@Styles装饰器可以快速定义并复用自定义样式。用于快速定义并复用自定义样式。

  • 当前@Styles仅支持通用属性和通用事件。
  • @Styles方法不支持参数,反例如下。
// 反例: @Styles不支持参数
@Styles function globalFancy (value: number) {
  .width(value)
}
  • @Styles可以定义在组件内或全局,在全局定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。
// 全局
@Styles function functionName() { ... }

// 在组件内
@Component
struct FancyUse {
  @Styles fancy() {
    .height(100)
  }
}
  • 定义在组件内的@Styles可以通过this访问组件的常量和状态变量,并可以在@Styles里通过事件来改变状态变量的值,示例如下:
@Component
struct FancyUse {
  @State heightValue: number = 100
  @Styles fancy() {
    .height(this.heightValue)
    .backgroundColor(Color.Yellow)
    .onClick(() => {
      this.heightValue = 200
    })
  }
}
  • 组件内@Styles的优先级高于全局@Styles。框架优先找当前组件内的@Styles,如果找不到,则会全局查找。

以下示例中演示了组件内@Styles和全局@Styles的用法

// 定义在全局的@Styles封装的样式
@Styles function globalFancy  () {
  .width(150)
  .height(100)
  .backgroundColor(Color.Pink)
}

@Entry
@Component
struct FancyUse {
  @State heightValue: number = 100
  // 定义在组件内的@Styles封装的样式
  @Styles fancy() {
    .width(200)
    .height(this.heightValue)
    .backgroundColor(Color.Yellow)
    .onClick(() => {
      this.heightValue = 200
    })
  }

  build() {
    Column({ space: 10 }) {
      // 使用全局的@Styles封装的样式
      Text('FancyA')
        .globalFancy ()
        .fontSize(30)
      // 使用组件内的@Styles封装的样式
      Text('FancyB')
        .fancy()
        .fontSize(30)
    }
  }
}

.4.4、@Extend装饰器:定义扩展组件样式

在前文的示例中,可以使用@Styles用于样式的扩展,在@Styles的基础上,我们提供了@Extend,用于扩展原生组件样式。

  • 和@Styles不同,@Extend仅支持定义在全局,不支持在组件内部定义。
  • 和@Styles不同,@Extend支持封装指定的组件的私有属性和私有事件和预定义相同组件的@Extend的方法。
// @Extend(Text)可以支持Text的私有属性fontColor
@Extend(Text) function fancy () {
  .fontColor(Color.Red)
}
// superFancyText可以调用预定义的fancy
@Extend(Text) function superFancyText(size:number) {
    .fontSize(size)
    .fancy()
}
  • 和@Styles不同,@Extend装饰的方法支持参数,开发者可以在调用时传递参数,调用遵循TS方法传值调用。
// xxx.ets
@Extend(Text) function fancy (fontSize: number) {
  .fontColor(Color.Red)
  .fontSize(fontSize)
}

@Entry
@Component
struct FancyUse {
  build() {
    Row({ space: 10 }) {
      Text('Fancy')
        .fancy(16)
      Text('Fancy')
        .fancy(24)
    }
  }
}
  • @Extend装饰的方法的参数可以为function,作为Event事件的句柄。
@Extend(Text) function makeMeClick(onClick: () => void) {
  .backgroundColor(Color.Blue)
  .onClick(onClick)
}

@Entry
@Component
struct FancyUse {
  @State label: string = 'Hello World';

  onClickHandler() {
    this.label = 'Hello ArkUI';
  }

  build() {
    Row({ space: 10 }) {
      Text(`${this.label}`)
        .makeMeClick(this.onClickHandler.bind(this))
    }
  }
}
  • @Extend的参数可以为状态变量,当状态变量改变时,UI可以正常的被刷新渲染。
@Extend(Text) function fancy (fontSize: number) {
  .fontColor(Color.Red)
  .fontSize(fontSize)
}

@Entry
@Component
struct FancyUse {
  @State fontSizeValue: number = 20
  build() {
    Row({ space: 10 }) {
      Text('Fancy')
        .fancy(this.fontSizeValue)
        .onClick(() => {
          this.fontSizeValue = 30
        })
    }
  }
}

.4.5、stateStyles:多态样式

@Styles和@Extend仅仅应用于静态页面的样式复用,stateStyles可以依据组件的内部状态的不同,快速设置不同样式。这就是我们本章要介绍的内容stateStyles(又称为:多态样式)。

stateStyles是属性方法,可以根据UI内部状态来设置样式,类似于css伪类,但语法不同。ArkUI提供以下四种状态:

  • focused:获焦态。
  • normal:正常态。
  • pressed:按压态。
  • disabled:不可用态。
@Entry
@Component
struct StateStylesSample {
  build() {
    Column() {
      Button('Button1')
        .stateStyles({
          focused: {
            .backgroundColor(Color.Pink)
          },
          pressed: {
            .backgroundColor(Color.Black)
          },
          normal: {
            .backgroundColor(Color.Red)
          }
        })
        .margin(20)
      Button('Button2')
        .stateStyles({
          focused: {
            .backgroundColor(Color.Pink)
          },
          pressed: {
            .backgroundColor(Color.Black)
          },
          normal: {
            .backgroundColor(Color.Red)
          }
        })
    }.margin('30%')
  }
}

在这里插入图片描述
@Styles和stateStyles联合使用
以下示例通过@Styles指定stateStyles的不同状态。

@Entry
@Component
struct MyComponent {
  @Styles normalStyle() {
    .backgroundColor(Color.Gray)
  }

  @Styles pressedStyle() {
    .backgroundColor(Color.Red)
  }

  build() {
    Column() {
      Text('Text1')
        .fontSize(50)
        .fontColor(Color.White)
        .stateStyles({
          normal: this.normalStyle,
          pressed: this.pressedStyle,
        })
    }
  }
}

在这里插入图片描述
stateStyles可以通过this绑定组件内的常规变量和状态变量。

@Entry
@Component
struct CompWithInlineStateStyles {
  @State focusedColor: Color = Color.Red;
  normalColor: Color = Color.Green

  build() {
    Column() {
      Button('clickMe').height(100).width(100)
        .stateStyles({
          normal: {
            .backgroundColor(this.normalColor)
          },
          focused: {
            .backgroundColor(this.focusedColor)
          }
        })
        .onClick(() => {
          this.focusedColor = Color.Pink
        })
        .margin('30%')
    }
  }
}

Button默认normal态显示绿色,第一次按下Tab键让Button获焦显示为focus态的红色,点击事件触发后,再次按下Tab键让Button获焦,focus态变为粉色。
在这里插入图片描述

状态管理

https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-state-management-overview-0000001524537145-V3
在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkUI中统称为状态管理机制。

自定义组件拥有变量,变量必须被装饰器装饰才可以成为状态变量,状态变量的改变会引起UI的渲染刷新。如果不使用状态变量,UI只能在初始化时渲染,后续将不会再刷新。 下图展示了State和View(UI)之间的关系。
在这里插入图片描述

  • View(UI):UI渲染,指将build方法内的UI描述和@Builder装饰的方法内的UI描述映射到界面。
  • State:状态,指驱动UI更新的数据。用户通过触发组件的事件方法,改变状态数据。状态数据的改变,引起UI的重新渲染。

.1、基本概念

  • 状态变量:被状态装饰器装饰的变量,状态变量值的改变会引起UI的渲染更新。示例:@State num: number = 1,其中,@State是状态装饰器,num是状态变量。
  • 常规变量:没有被状态装饰器装饰的变量,通常应用于辅助计算。它的改变永远不会引起UI的刷新。以下示例中increaseBy变量为常规变量。
  • 数据源/同步源:状态变量的原始来源,可以同步给不同的状态数据。通常意义为父组件传给子组件的数据。以下示例中数据源为count: 1。
  • 命名参数机制:父组件通过指定参数传递给子组件的状态变量,为父子传递同步参数的主要手段。示例:CompA: ({ aProp: this.aProp })。
  • 从父组件初始化:父组件使用命名参数机制,将指定参数传递给子组件。子组件初始化的默认值在有父组件传值的情况下,会被覆盖。示例:
@Component
struct MyComponent {
  @State count: number = 0;
  private increaseBy: number = 1;

  build() {
  }
}

@Component
struct Parent {
  build() {
    Column() {
      // 从父组件初始化,覆盖本地定义的默认值
      MyComponent({ count: 1, increaseBy: 2 })
    }
  }
}
  • 初始化子节点:父组件中状态变量可以传递给子组件,初始化子组件对应的状态变量。示例同上。
  • 本地初始化:在变量声明的时候赋值,作为变量的默认值。示例:@State count: number = 0。

.2、装饰器总览

ArkUI提供了多种装饰器,通过使用这些装饰器,状态变量不仅可以观察在组件内的改变,还可以在不同组件层级间传递,比如父子组件、跨组件层级,也可以观察全局范围内的变化。根据状态变量的影响范围,将所有的装饰器可以大致分为:

  • 管理组件拥有状态的装饰器:组件级别的状态管理,可以观察组件内变化,和不同组件层级的变化,但需要唯一观察同一个组件树上,即同一个页面内。
  • 管理应用拥有状态的装饰器:应用级别的状态管理,可以观察不同页面,甚至不同UIAbility的状态变化,是应用内全局的状态管理。

从数据的传递形式和同步类型层面看,装饰器也可分为:

  • 只读的单向传递;
  • 可变更的双向传递。

图示如下,具体装饰器的介绍,可详见管理组件拥有的状态和管理应用拥有的状态。开发者可以灵活地利用这些能力来实现数据和UI的联动。
在这里插入图片描述
上图中,Components部分的装饰器为组件级别的状态管理,Application部分为应用的状态管理。开发者可以通过@StorageLink/@LocalStorageLink实现应用和组件状态的双向同步,通过@StorageProp/@LocalStorageProp实现应用和组件状态的单向同步。

管理组件拥有的状态,即图中Components级别的状态管理:

  • @State:@State装饰的变量拥有其所属组件的状态,可以作为其子组件单向和双向同步的数据源。当其数值改变时,会引起相关组件的渲染刷新。
  • @Prop:@Prop装饰的变量可以和父组件建立单向同步关系,@Prop装饰的变量是可变的,但修改不会同步回父组件。
  • @Link:@Link装饰的变量和父组件构建双向同步关系的状态变量,父组件会接受来自-@Link装饰的变量的修改的同步,父组件的更新也会同步给@Link装饰的变量。
  • @Provide/@Consume:@Provide/@Consume装饰的变量用于跨组件层级(多层组件)同步状态变量,可以不需要通过参数命名机制传递,通过alias(别名)或者属性名绑定。
  • @Observed:@Observed装饰class,需要观察多层嵌套场景的class需要被@Observed装饰。单独使用@Observed没有任何作用,需要和@ObjectLink、@Prop连用。
  • @ObjectLink:@ObjectLink装饰的变量接收@Observed装饰的class的实例,应用于观察多层嵌套场景,和父组件的数据源构建双向同步。

管理应用拥有的状态,即图中Application级别的状态管理:

  • AppStorage是应用程序中的一个特殊的单例LocalStorage对象,是应用级的数据库,和进程绑定,通过@StorageProp和@StorageLink装饰器可以和组件联动。
  • AppStorage是应用状态的“中枢”,将需要与组件(UI)交互的数据存入AppStorage,比如持久化数据PersistentStorage和环境变量Environment。UI再通过AppStorage提供的装饰器或者API接口,访问这些数据。
  • 框架还提供了LocalStorage,AppStorage是LocalStorage特殊的单例。LocalStorage是应用程序声明的应用状态的内存“数据库”,通常用于页面级的状态共享,通过@LocalStorageProp和@LocalStorageLink装饰器可以和UI联动。

.2.1、其他状态管理功能

@Watch用于监听状态变量的变化。
$$运算符:给内置组件提供TS变量的引用,使得TS变量和内置组件的内部状态保持同步。

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 配置 Android SDK 的步骤如下: 1. 下载 Android Studio,它是 Android SDK 的官方 IDE。 2. 安装 Android Studio,并启动它。 3. 在 Android Studio 中打开 SDK Manager,它可以在 "Welcome to Android Studio" 窗口中找到,或者通过菜单栏中的 "SDK Manager" 选项。 4. 在 SDK Manager 中选择要安装的 Android 版本,并点击 "Apply" 按钮安装所选的版本。 5. 在 Android Studio 中创建一个新的 Android 项目,并选择所安装的 Android 版本作为目标版本。 6. 完成配置,现在可以开始使用 Android SDK 开发 Android 应用了。 ### 回答2: 在配置 Android SDK 之前,您需要先下载 Android Studio。Android Studio 是一个强大的开发工具,它可以帮助您开发 Android 应用程序。在下载 Android Studio 后,您将拥有 Eclipse 和 Android SDK 的所有功能,并且还可以轻松使用 Gradle(一种构建工具)构建您的应用程序。 一旦您已经安装了 Android Studio,就可以开始配置 Android SDK 了。Android SDK 是 Android 开发工具包,它包含了所有开发 Android 应用程序所需的工具和资源。配置 Android SDK 可以让您的 Android 应用程序开发更加顺畅和高效。 下面是在 Android Studio 中配置 Android SDK 的步骤: 1. 打开 Android Studio,并单击“Welcome to Android Studio”。 2. 在 “Welcome to Android Studio” 页面中,单击 “Configure” 选项。 3. 在 “Configure” 页面中,单击 “SDK Manager”。 4. 在 “SDK Manager” 页面中,您将看到 Android SDK 的所有版本。选择您要使用的版本,然后单击 “OK”。 5. 在 “SDK Manager” 页面的左侧栏中,您可以选择安装或卸载不同组件。如果您只需要基本的 Android 开发工具,则可以只安装“Android SDK Platform-Tools”和“Android SDK Build-Tools”。这些工具是构建和编译 Android 应用程序所必需的。 6. 单击 “Apply” 按钮,然后单击 “OK” 按钮。 7. Android Studio 将开始下载和安装所有所选组件。下载和安装时间可能需要一些时间,具体取决于您的计算机速度和网络连接。 8. 安装完成后,您可以通过单击 “OK” 按钮关闭 SDK Manager 并开始使用 Android Studio 进行开发。 以上就是在 Android Studio 中配置 Android SDK 的步骤。配置 Android SDK 可以让您更轻松地开发 Android 应用程序,也可以确保您具有所需的工具和资源来构建高质量的应用程序。 ### 回答3: Android SDK 配置是移动开发的必要步骤。Android SDK 包含了用于开发 Android 应用程序所需的工具、平台和库。在配置 Android SDK 之前,首先需要确定所需要开发的 Android 系统版本以及需要使用的开发工具。 以下是配置 Android SDK 的步骤: 1. 下载并安装 Android Studio Android Studio 是 Google 推出的官方 IDE,可以帮助开发人员创建高质量的 Android 应用程序。访问 Android 官网,下载最新版本的 Android Studio,并按照指示安装。 2. 安装并配置 Java JDK Android 开发需要使用 Java JDK,因此需要先进行安装和配置。可以从官方网站下载最新版本的 Java JDK,然后按照安装向导进行安装。 3. 启动 Android Studio 并配好 SDK 环境 在 Android Studio 启动后,需要配置 SDK 环境。点击“Welcome to Android Studio”页面上面的“Configure”选项,选择“SDK Manager”。 在“SDK Platforms”页面上,选择所需要的 Android 系统版本进行安装。如果需要开发 Android 应用程序,需要至少安装一个 Android 平台。在“SDK Tools”页面上,可以安装 Android SDK 的其他工具和服务。 4. 配置 Android 虚拟机 Android Studio 提供了 Android 虚拟机(AVD)来测试应用程序。可以在“AVD Manager”中创建虚拟设备,选择所需的设备类型和 Android 系统版本。完成后,可以启动 AVD 进行测试。 以上就是配置 Android SDK 的基本步骤。配置好 Android SDK 后,开发人员就可以开始使用 Android Studio 开发 Android 应用程序。当然在开发的时候要注意一些细节问题,例如项目配置,应用程序测试等问题,这些也是需要重视的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值