场景介绍
标准化数据类型(Uniform Type Descriptor,简称UTD)用于解决系统中的类型模糊问题,即针对同一种数据类型,存在不同的类型描述方式:MIME Type、文件扩展名等。例如描述jpg/jpeg类型图片时,可以使用image/jpeg、.jpg、.jpeg或image/picture等方式进行描述。
当相关类型的数据进行跨应用、跨设备传输时,目标端应用/设备需要进行多方面的适配,才能够对数据内容进行相关处理,且存在无法识别的情况。
标准化数据类型分为预置数据类型和应用自定义数据类型。并且支持从其他类型体系,如文件名后缀和MIME type转换为UTD标准类型。
针对标准化数据类型,典型的应用场景有:文件管理中的图片预览、系统分享等。
标准化数据类型按层级结构构建
基于MIME Type或文件后缀名进行类型区分,存在另一个不足:即扁平化的数据类型定义。
扁平/松散的类型定义难以描述不同类型间的兼容与继承关系,且在实际使用过程中,会增加应用处理数据类型时的开发复杂度。例如搜索场景,用户从精确地搜索动物相关的任意类型图片,进一步扩展到动物相关的任意图片、视频或音频资源。为了满足上述场景,我们需要在定义数据类型时,支持类型层级结构。
构建标准类型的层级结构,定义层级结构中的类型归属关系,能够帮助系统、应用实现数据类型的分层、分类管理。当用户进行数据分享或拖拽时,如果数据中同时包含图片、视频、音频等内容,系统/应用可以根据层级按需对分享内容进行整理,如分享了几张照片、几条视频或几个媒体资源文件等。
标准化数据类型的分类原则
UTD中定义的标准化数据类型在设计原则上按物理和逻辑分为两类。图中涉及的标准化数据类型可见UniformDataType。
-
按物理分类的根节点为general.entity,用于描述类型的物理属性,比如文件、目录等,具体可见图1。
-
按逻辑分类的根节点为general.object,用于描述类型的功能性特征,如图片、网页等,具体可见图2。
按照此分类原则,可以从两个维度对数据类型进行描述。如描述图片时,可以是一个图片对象,同时也可以是一个文件。
并非所有的格式都具有两个维度,如general.calendar,更多的注重calendar对象的功能性描述。
图1 物理标准化数据类型示意图
图2 逻辑标准化数据类型示意图
标准化数据类型的定义
标准化数据类型包含了标准化数据类型的标识ID、归属类型关系、简要描述等信息,具体可见TypeDescriptor属性,每个类型定义具体包含以下内容:
- typeId: 定义标准化数据类型的ID,该ID具有唯一性。
- belongingToTypes: 定义标准化数据类型的归属关系,即该标准化数据类型归属于哪个更高层级的类型,允许存在一个标准化数据类型归属于多个类型的情况。
- description: 标准化数据类型的简要说明。
- referenceURL: 标准化数据类型的参考链接URL,用于描述类型的详细信息。
- iconFile: 标准化数据类型的默认图标文件路径,可能为空字符串(即没有默认图标),应用可以自行决定是否使用该默认图标。
- filenameExtensions: 标准化数据类型所关联的文件名后缀列表。
- mimeTypes: 标准化数据类型所关联的多用途互联网邮件扩展类型列表。
预置数据类型
基于常用的数据类型,预先定义了一部分标准数据类型描述符,即预置数据类型。如用于描述音频文件的“general.audio”,描述视频文件的“general.video”,更多预置数据类型参考 UniformDataType。
应用自定义数据类型
由于预置标准数据类型无法穷举所有数据类型,在业务跨应用、跨设备交互过程中,会涉及到一些应用独有的数据类型,因此支持应用声明自定义数据类型。
应用自定义的数据类型可继承已有的标准类型,例如业务自定义的图片类型可以使用“com.company.x-image”作为自定义数据类型的标识。
业务可以将自定义数据类型注册到系统中,这样其他业务可以在需要时引用,进而实现生态内各应用自定义数据类型的共享与统一。
工作原理
基于标准类型的层级结构,业务声明自己支持的数据类型标识符时,需要声明该类型标识符的层级逻辑,例如业务自定义图片类型UTD标识符“com.company.x-image”,并归属到general.image类中。UTD会检验自定义类型标识符,确保归属关系中不出现环状结构。
应用安装时,UTD会读取应用中自定义的数据类型进行安装,校验自定义类型数据符合约束条件后,应用自定义数据类型将被安装到设备中。应用启动后能正常读取到应用自定义的数据类型。如果引用其他应用定义的自定义数据类型,需要在应用开发时一并写入自定义数据类型配置文件中。
约束限制
针对自定义的类型描述各字段,有以下相关要求和限制:
-
TypeId: 定义标准化数据类型的ID,该ID具有唯一性,由应用bundleName + 具体类型名组成,不可缺省,允许包含数字、大小写字母、-和.。
-
BelongingToTypes: 定义标准化数据类型的归属关系,即该标准化数据类型归属于哪个更高层级的类型,所属类型可以为多个,但是必须为已存在的数据
类型(标准化数据类型预置类型或其他新增自定义数据类型),不能为应用自定义类型本身,不能为空,且与现有标准化数据类型、其他新增自定义数据类型不能形成环行依赖结构。
-
FilenameExtensions: 应用自定义标准化数据类型所关联的文件后缀。可以缺省;可以为多个,每个后缀为以.开头且长度不超过127的字符串。
-
MIMETypes: 应用自定义标准化数据类型所关联的web消息数据类型。可以缺省;可以为多个,每个类型为长度不超过127的字符串。
-
Description: 应用自定义标准化数据类型的简要说明。可以缺省;填写时,长度为不超过255的字符串。
-
ReferenceURL: 应用自定义标准化数据类型的参考链接URL,用于描述类型的详细信息。可以缺省;填写时,长度为不超过255的字符串。
开发步骤
下面以新增媒体类文件类型场景为例,说明如何自定义UTD标准化数据类型。
-
当前应用在entry\src\main\resources\rawfile\arkdata\utd\目录下新增utd.json5文件。
-
在当前应用的utd.json5配置文件内新增所需的自定义数据类型。
{
"UniformDataTypeDeclarations": [
{
"TypeId": "com.example.myFirstHap.image",
"BelongingToTypes": ["general.image"],
"FilenameExtensions": [".myImage", ".khImage"],
"MIMETypes": ["application/myImage", "application/khImage"],
"Description": "My Image.",
"ReferenceURL": ""
},
{
"TypeId": "com.example.myFirstHap.audio",
"BelongingToTypes": ["general.audio"],
"FilenameExtensions": [".myAudio", ".khAudio"],
"MIMETypes": ["application/myAudio", "application/khAudio"],
"Description": "My audio.",
"ReferenceURL": ""
},
{
"TypeId": "com.example.myFirstHap.video",
"BelongingToTypes": ["general.video"],
"FilenameExtensions": [".myVideo", ".khVideo"],
"MIMETypes": ["application/myVideo", "application/khVideo"],
"Description": "My video.",
"ReferenceURL": ""
}
]
}
-
如果其他应用要直接使用当前应用内的自定义数据类型,需要在其应用的entry\src\main\resources\rawfile\arkdata\utd\目录下新增utd.json5文件。
然后在utd.json5配置文件中进行以下声明:
{
"ReferenceUniformDataTypeDeclarations": [
{
"TypeId": "com.example.myFirstHap.image",
"BelongingToTypes": ["general.image"],
"FilenameExtensions": [".myImage", ".khImage"],
"MIMETypes": ["application/myImage", "application/khImage"],
"Description": "My Image.",
"ReferenceURL": ""
}
]
}
-
其他应用也可以在DevEco Studio中创建utd.json5模板,在模板中引用当前应用内的自定义数据类型之后,基于已引用的自定义数据类型进行自定义。同时,DevEco Studio还会对配置文件中的字段进行格式校验,utd.json5配置文件示例如下:
{
"UniformDataTypeDeclarations": [
{
"TypeId": "com.example.mySecondHap.image",
"BelongingToTypes": ["com.example.myFirstHap.image"],
"FilenameExtensions": [".myImageEx", ".khImageEx"],
"MIMETypes": ["application/my-ImageEx", "application/khImageEx"],
"Description": "My Image extension.",
"ReferenceURL": ""
}
]
}
接口说明
以下是UTD常用接口说明,对于预置数据类型和应用自定义数据类型同样适用,更多接口和详细说明,请见 @ohos.data.uniformTypeDescriptor (标准化数据定义与描述)。
接口名称 | 描述 |
---|---|
UniformDataType | 标准化数据类型的枚举定义。此处不再展开列举各枚举。 |
belongsTo(type: string): boolean | 判断当前标准化数据类型是否归属于指定的标准化数据类型。 |
isLowerLevelType(type: string): boolean | 判断当前标准化数据类型是否是指定标准化数据类型的低层级类型。 |
isHigherLevelType(type: string): boolean | 判断当前标准化数据类型是否是指定标准化数据类型的高层级类型。 |
getUniformDataTypeByFilenameExtension(filenameExtension: string, belongsTo?: string): string | 根据给定的文件后缀名和所归属的标准化数据类型查询标准化数据类型的ID。 |
getUniformDataTypeByMIMEType(mimeType: string, belongsTo?: string): string | 根据给定的MIME类型和所归属的标准化数据类型查询标准化数据类型的ID。 |
如何查询媒体类文件归属类型
下面以媒体类文件的归属类型查询场景为例,说明如何使用UTD。
- 导入uniformTypeDescriptor模块。
- 可根据 “.mp3” 文件后缀查询对应UTD数据类型,并查询对应UTD数据类型的具体属性。
- 可根据 “audio/mp3” MIMEType查询对应UTD数据类型,并查询对应UTD数据类型的具体属性。
- 将上述步骤查询出来的数据类型进行比较,确认类型是否相等。
- 根据上述步骤中查询到的标准数据类型“general.mp3”与表示音频数据的已知标准数据类型“general.audio”做比较查询,确认是否存在归属关系。
// 1.导入模块
import { uniformTypeDescriptor } from '@kit.ArkData';
try {
// 2.可根据 “.mp3” 文件后缀查询对应UTD数据类型,并查询对应UTD数据类型的具体属性
let fileExtention = '.mp3';
let typeId1 = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension(fileExtention);
let typeObj1 = uniformTypeDescriptor.getTypeDescriptor(typeId1);
console.info('typeId:' + typeObj1.typeId);
console.info('belongingToTypes:' + typeObj1.belongingToTypes);
console.info('description:' + typeObj1.description);
console.info('referenceURL:' + typeObj1.referenceURL);
console.info('filenameExtensions:' + typeObj1.filenameExtensions);
console.info('mimeTypes:' + typeObj1.mimeTypes);
// 3.可根据 “audio/mp3” MIMEType查询对应UTD数据类型,并查询对应UTD数据类型的具体属性。
let mineType = 'audio/mp3';
let typeId2 = uniformTypeDescriptor.getUniformDataTypeByMIMEType(mineType);
let typeObj2 = uniformTypeDescriptor.getTypeDescriptor(typeId2);
console.info('typeId:' + typeObj2.typeId);
console.info('belongingToTypes:' + typeObj2.belongingToTypes);
console.info('description:' + typeObj2.description);
console.info('filenameExtensions:' + typeObj2.filenameExtensions);
console.info('mimeTypes:' + typeObj2.mimeTypes);
// 4.将数据类型进行比较,确认是否同一种数据类型
if (typeObj1 != null && typeObj2 != null) {
let ret = typeObj1.equals(typeObj2);
console.info('typeObj1 equals typeObj2, ret:' + ret);
}
// 5.将查询到的标准数据类型“general.mp3”与表示音频数据的已知标准数据类型“general.audio”做比较查询,确认是否存在归属关系。
if (typeObj1 != null) {
let ret = typeObj1.belongsTo('general.audio');
console.info('belongsTo, ret:' + ret);
let mediaTypeObj = uniformTypeDescriptor.getTypeDescriptor('general.media');
ret = mediaTypeObj.isHigherLevelType('general.audio'); // 确认是否存在归属关系
console.info('isHigherLevelType, ret:' + ret);
}
} catch (err) {
console.error('err message:' + err.message + ', err code:' + err.code);
}
如何通过文件后缀获取对应的MIMEType列表
下面以通过“.mp3”文件后缀获取对应的MIMEType列表为例,说明如何通过文件后缀获取对应的MIMEType列表。
- 导入uniformTypeDescriptor模块。
- 可根据 “.mp3” 文件后缀查询对应UTD数据类型。
- 根据UTD数据类型查询对应的MIMEType列表。
// 1.导入模块
import { uniformTypeDescriptor } from '@kit.ArkData';
try {
// 2.可根据 “.mp3” 文件后缀查询对应UTD数据类型。
let fileExtention = '.mp3';
let typeId = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension(fileExtention);
// 3.根据UTD数据类型查询对应的MIMEType列表。
let typeObj = uniformTypeDescriptor.getTypeDescriptor(typeId);
let mimeTypes = typeObj.mimeTypes;
console.info('mimeTypes:' + mimeTypes);
} catch (err) {
console.error('err message:' + err.message + ', err code:' + err.code);
}
如何通过MIMEType获取对应的后缀列表
下面以通过“audio/mp3”MIMEType获取对应文件后缀列表为例,说明如何通过MIMEType获取对应的后缀列表。
- 导入uniformTypeDescriptor模块。
- 可根据 “audio/mp3” MIMEType查询对应UTD数据类型。
- 根据UTD数据类型查询对应的MIMEType列表。
// 1.导入模块
import { uniformTypeDescriptor } from '@kit.ArkData';
try {
// 2.可根据 “audio/mp3” MIMEType查询对应UTD数据类型。
let mineType = 'audio/mp3';
let typeId = uniformTypeDescriptor.getUniformDataTypeByMIMEType(mineType);
// 3. 根据UTD数据类型查询对应的MIMEType列表
let typeObj = uniformTypeDescriptor.getTypeDescriptor(typeId);
let filenameExtensions = typeObj.filenameExtensions;
console.info('filenameExtensions:' + filenameExtensions);
} catch (err) {
console.error('err message:' + err.message + ', err code:' + err.code);
}
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。
点击领取→【纯血版鸿蒙全套最新学习资料】(安全链接,放心点击)希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取~限时开源!!
鸿蒙(HarmonyOS NEXT)最新学习路线
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、(南向驱动、嵌入式等)鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
HarmonyOS Next 最新全套视频教程
《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建
《鸿蒙开发基础》
- ArkTS语言
- 安装DevEco Studio
- 运用你的第一个ArkTS应用
- ArkUI声明式UI开发
- .……
《鸿蒙开发进阶》
- Stage模型入门
- 网络管理
- 数据管理
- 电话服务
- 分布式应用开发
- 通知与窗口管理
- 多媒体技术
- 安全技能
- 任务管理
- WebGL
- 国际化开发
- 应用测试
- DFX面向未来设计
- 鸿蒙系统移植和裁剪定制
- ……
《鸿蒙进阶实战》
- ArkTS实践
- UIAbility应用
- 网络案例
- ……
大厂面试必问面试题
鸿蒙南向开发技术
鸿蒙APP开发必备
请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结
总的来说,华为鸿蒙不再兼容安卓,对程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,才能在这个变革的时代中立于不败之地。