写点什么

OpenHarmony 资源管理详解

作者:坚果
  • 2022 年 7 月 04 日
  • 本文字数:3819 字

    阅读完需:约 13 分钟

本节笔者向读者介绍一下 OpenHarmony 应用的资源分类和资源的访问方式。废话不多说,我们直接开始。

资源分类

移动端应用开发常用到的资源比如图片,音视频,字符串等都有固定的存放目录,OpenHarmony 把这些应用的资源文件统一放在 resources 目录下的各子目录中便于开发者使用和维护, resoures 目录包括两大类,实际为一类,为 base 目录与限定词目录,另一类为 rawfile 目录(不知道是不是官方文档有误,我已经提了 Issue)。新建 OpenHarmony 应用,默认生成的资源目录如下所示:


在这儿,我发现官方文档的错误之处,也已经做了修改。提了 PR,等修复。


base 目录与限定词目录下面可以创建资源组目录(包括 elementmediaanimationlayoutgraphicprofile 等),用于存放特定类型的资源文件,各资源目录说明如下图所示:


资源组目录

注意,都是以键值对的形式存在,name 不能重复,value 可以重复,但我相信,既然 name 都不重复,value 肯定也不会重复,不然意义何在。


限定词目录

限定词目录可以由一个或多个表征应用场景或设备特征的限定词组合而成,包括移动国家码和移动网络码、语言、文字、国家或地区、横竖屏、设备类型、颜色模式和屏幕密度等维度,限定词之间通过下划线(_)或者中划线(-)连接。开发者在创建限定词目录时,需要掌握限定词目录的命名要求,以及限定词目录与设备状态的匹配规则。


限定词取值要求

不显示表格,呜呜呜😩



限定词目录与设备状态的匹配规则


  • 在为设备匹配对应的资源文件时,限定词目录匹配的优先级从高到低依次为:移动国家码和移动网络码 > 区域(可选组合:语言、语言_文字、语言_国家或地区、语言_文字_国家或地区)> 横竖屏 > 设备类型 > 颜色模式 > 屏幕密度。

  • 如果限定词目录中包含移动国家码和移动网络码、语言、文字、横竖屏、设备类型、颜色模式限定词,则对应限定词的取值必须与当前的设备状态完全一致,该目录才能够参与设备的资源匹配。例如,限定词目录“zh_CN-car-ldpi”不能参与“en_US”设备的资源匹配。


当然也可以自己创建目录,将图片等文件统一存放,比如,我将图片存放在自己创建的“/common/images”目录,这样的话,目录中的资源文件会被直接打包进应用,不经过编译,也不会被赋予资源文件 ID。这一点需要大家注意。

资源访问

OpenHarmony 应用资源目录分为三类,一类是应用资源目录,另一类是系统资源目录,还有就是自己创建的目录。


它们的资源访问方式如下:


  • 访问应用资源目录

  • base 目录下的资源文件会被编译成二进制文件并且给这些资源赋予唯一的 ID ,使用相应资源的时候通过资源访问符 $('app.type.name') 的形式,app 代表是应用内 resources 目录中定义的资源;type 表示资源类型,可取值有 colorfloatstringstringmedia 等;name 表示资源的文件名字。例如 media 中新加 name 为 Car.svg 的图片,则访问该字符串资源为 $r('app.media.Car')

  • 笔者在 base 目录下新建 string.jsoncolor.json 文件,分别存放字符串和颜色,资源内容如下图所示:


  • 通过 $('app.type.name') 访问资源的简单样例如下所示:


  @Entry  @Component  struct Index {      build() {      Row() {        Column() {          Text($r('app.string.title_desc'))       // 访问字符串资源            .fontSize(60).fontWeight(FontWeight.Bold)              .fontColor($r('app.color.title_color')) // 访问字体颜色            .backgroundImage($r('app.media.Car')) // 设备背景图片          Image("common/images/Car.svg").objectFit(ImageFit.Contain).height(200)        }        .width('100%')      }      .height('100%')    }  }
复制代码


样例运行结果如下图所示:



  • 访问系统资源

  • 系统资源包含 颜色圆角字体间距字符串图片 等,通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,开发者可以通过 $r('sys.type.name') 的形式引用系统资源,和访问应用资源不同的是使用 sys 代表系统资源,其它和访问应用资源规则一致。

  • 访问系统资源简单样例如下所示:


  @Entry  @Component  struct ResourceTest {    build() {      Column() {        Text($r('app.string.title_desc')) //**访问应用资源目录**          .fontColor($r('sys.color.ohos_fa_alert')) //**访问系统资源目录**          .fontSize($r('sys.float.ohos_id_text_size_headline3'))          .backgroundColor($r('sys.color.ohos_id_color_palette_aux1'))        Image("/common/images/Car.svg") //**自己创建的目录**          .objectFit(ImageFit.None)          .border({            color: Color.Orange,            radius: 20,            width: 12          })          .margin({            top: 50,            })          .width(200)          .height(200)        }      .padding(20)      .width("100%")      .height("100%")    }  }
复制代码


样例运行结果如下图所示:


访问自己创建的目录


我们还可以将图片文件存放在自己创建的“/common/images”目录


使用很简单,如下图所示:


Image("/common/images/Car.svg") //**自己创建的目录**        .objectFit(ImageFit.None)        .border({          color: Color.Orange,          radius: 20,          width: 12        })        .margin({          top: 50,
}) .width(200) .height(200)
复制代码


运行效果



资源管理器

ArkUI 开发框架在 @ohos.resourceManager 模块里提供了资源管理器 ResourceManager,它可以访问不同的资源,比如获取获取字符串资源,获取设备配置信息等等,resourceManager 模块提供部分 API 如下所示:


declare namespace resourceManager {// 获取ResourceManagerexport function getResourceManager(callback: AsyncCallback<ResourceManager>): void;// 获取指定bundleName的ResourceManagerexport function getResourceManager(bundleName: string, callback: AsyncCallback<ResourceManager>): void;
export interface ResourceManager { // 获取字符串资源 getString(resId: number, callback: AsyncCallback<string>): void; // 获取字符串数组资源 getStringArray(resId: number, callback: AsyncCallback<Array<string>>): void; // 获取媒体资源 getMedia(resId: number, callback: AsyncCallback<Uint8Array>): void; // 获取设备信息,比如当前屏幕密度,设备类型是手机还是平板等 getDeviceCapability(callback: AsyncCallback<DeviceCapability>): void; // 获取配置信息,比如当前屏幕方向密度,当前设备语言 getConfiguration(callback: AsyncCallback<Configuration>): void; // 释放ResourceManager资源 release(); }}export default resourceManager;
复制代码


使用 ResourceManager 之前先调用 getResourceManager() 方法获取它,然后再调用 ResourceManager 的各种 getXXX() 方法获取对应资源, ResourceManager 使用流程如下所示:


  • 引入 resourceManager


  import resourceManager from '@ohos.resourceManager';
复制代码


  • 获取 ResourceManager


  aboutToAppear() {    resourceManager.getResourceManager((error, manager) => {      // 获取manager    })  }
复制代码


  • 使用 ResourceManager


  manager.getString(0x1000001, (innerError, data) => {    if(data) {      // 获取资源成功    } else {      console.log("error: " + JSON.stringify(innerError))    }  })
复制代码


完整样例如下所示:


import resourceManager from '@ohos.resourceManager';
@Entry @Component struct ResourceTest {
@State text_string: string = "跟着坚果学习"; @State capability: string = "OpenHarmony"; @State configuration: string = "应用开发";
aboutToAppear() { resourceManager.getResourceManager((error, manager) => { manager.getString(0x1000001, (innerError, data) => { if(data) { this.text_string = data; } else { console.log("error: " + JSON.stringify(innerError)); } })
manager.getDeviceCapability((innerError, deviceCapability) => { if(deviceCapability) { this.capability = JSON.stringify(deviceCapability); } })
manager.getConfiguration((innerError, configuration) => { if(configuration) { this.configuration = JSON.stringify(configuration); } }) }) }
build() { Column({ }) { Text(this.text_string) // 访问字符串资源 // 设置尺寸 .fontSize(29) .fontColor($r('app.color.title_color')) // 访问字体颜色

Text(this.capability) // capability信息 .fontSize(40).fontWeight(FontWeight.Bold)
Text(this.configuration) // configuration信息 .fontSize(60) } .width('100%') .height('100%') .padding(10) }}
复制代码


样例运行结果如下图所示:



发布于: 刚刚阅读数: 3
用户头像

坚果

关注

此间若无火炬,我便是唯一的光 2020.10.25 加入

公众号:“大前端之旅”,华为云享专家,InfoQ签约作者,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

评论

发布
暂无评论
OpenHarmony资源管理详解_HarmonyOS_坚果_InfoQ写作社区