#夏日挑战赛#OpenHarmony资源管理详解 原创 精华

鸿蒙坚果派
发布于 2022-7-5 00:07
浏览
1收藏

「本文正在参加星光计划3.0–夏日挑战赛」

#资源管理

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

资源分类

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

#夏日挑战赛#OpenHarmony资源管理详解-鸿蒙开发者社区
base 目录与限定词目录下面可以创建资源组目录(包括 elementmediaanimationlayoutgraphicprofile 等),用于存放特定类型的资源文件,各资源目录说明如下图所示:

资源组目录

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

资源组目录 目录说明 资源文件
element 表示元素资源,以下每一类数据都采用相应的JSON文件来表征。<br /> - boolean,布尔型<br /> - color,颜色<br /> - float,浮点型 <br />- intarray,整型数组 <br />- integer,整型 <br />- pattern,样式 <br />- plural,复数形式<br /> - strarray,字符串数组<br /> - string,字符串 element目录中的文件名称建议与下面的文件名保持一致。每个文件中只能包含同一类型的数据。<br /> - boolean.json<br /> - color.json <br />- float.json <br />- intarray.json <br />- integer.json<br />- pattern.json<br /> - plural.json <br />- strarray.json <br />- string.json
media 表示媒体资源,包括图片、音频、视频等非文本格式的文件。 文件名可自定义,例如:icon.png。
animation 表示动画资源,采用XML文件格式。 文件名可自定义,例如:zoom_in.xml。
layout 表示布局资源,采用XML文件格式。 文件名可自定义,例如:home_layout.xml。
graphic 表示可绘制资源,采用XML文件格式。 文件名可自定义,例如:notifications_dark.xml。
profile 表示其他类型文件,以原始文件形式保存。 文件名可自定义。

限定词目录

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

限定词取值要求

限定词类型 含义与取值说明
移动国家码和移动网络码 移动国家码(MCC)和移动网络码(MNC)的值取自设备注册的网络。MCC后面可以跟随MNC,使用下划线(_)连接,也可以单独使用。<br />例如:<br />mcc460表示中国,<br />mcc460_mnc00表示中国_中国移动。<br /> 详细取值范围,请查阅ITU-T E.212(国际电联相关标准)。
语言 表示设备使用的语言类型,由2~3个小写字母组成。例如:zh表示中文,en表示英语,mai表示迈蒂利语。 详细取值范围,请查阅ISO 639(ISO制定的语言编码标准)。
文字 表示设备使用的文字类型,由1个大写字母(首字母)和3个小写字母组成。<br />例如:<br />Hans表示简体中文,<br />Hant表示繁体中文。 <br />详细取值范围,请查阅ISO 15924(ISO制定的文字编码标准)。
国家或地区 表示用户所在的国家或地区,由2~3个大写字母或者3个数字组成。例如:<br />CN表示中国,<br />GB表示英国。<br />详细取值范围,请查阅ISO 3166-1(ISO制定的国家和地区编码标准)。
横竖屏 表示设备的屏幕方向,取值如下:<br /> - vertical:竖屏<br /> - horizontal:横屏
设备类型 表示设备的类型,取值如下:<br /> - car:车机 <br />- tv:智慧屏 <br />- wearable:智能穿戴
颜色模式 表示设备的颜色模式,取值如下: - dark:深色模式 - light:浅色模式
屏幕密度 表示设备的屏幕密度(单位为dpi),取值如下:<br /> - sdpi:表示小规模的屏幕密度(Small-scale Dots Per Inch),适用于dpi取值为(0, 120]的设备。<br /> - mdpi:表示中规模的屏幕密度(Medium-scale Dots Per Inch),适用于dpi取值为(120, 160]的设备。 <br />- ldpi:表示大规模的屏幕密度(Large-scale Dots Per Inch),适用于dpi取值为(160, 240]的设备。 <br />- xldpi:表示特大规模的屏幕密度(Extra Large-scale Dots Per Inch),适用于dpi取值为(240, 320]的设备。 <br />- xxldpi:表示超大规模的屏幕密度(Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(320, 480]的设备。<br /> - xxxldpi:表示超特大规模的屏幕密度(Extra Extra Extra Large-scale Dots Per Inch),适用于dpi取值为(480, 640]的设备。

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

  • 在为设备匹配对应的资源文件时,限定词目录匹配的优先级从高到低依次为:移动国家码和移动网络码 > 区域(可选组合:语言、语言_文字、语言_国家或地区、语言_文字_国家或地区)> 横竖屏 > 设备类型 > 颜色模式 > 屏幕密度。
  • 如果限定词目录中包含移动国家码和移动网络码、语言、文字、横竖屏、设备类型、颜色模式限定词,则对应限定词的取值必须与当前的设备状态完全一致,该目录才能够参与设备的资源匹配。例如,限定词目录“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 文件,分别存放字符串和颜色,资源内容如下图所示:

#夏日挑战赛#OpenHarmony资源管理详解-鸿蒙开发者社区

通过 $(‘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%')
  }
}

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

#夏日挑战赛#OpenHarmony资源管理详解-鸿蒙开发者社区

  • 访问系统资源

    系统资源包含 颜色圆角字体间距字符串图片 等,通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,开发者可以通过 $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%")
      }
    }
    

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

#夏日挑战赛#OpenHarmony资源管理详解-鸿蒙开发者社区

访问自己创建的目录

我们还可以将图片文件存放在自己创建的“/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)

运行效果

#夏日挑战赛#OpenHarmony资源管理详解-鸿蒙开发者社区

资源管理器

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

declare namespace resourceManager {
// 获取ResourceManager
export function getResourceManager(callback: AsyncCallback<ResourceManager>): void;
// 获取指定bundleName的ResourceManager
export 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)
  }
}

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

#夏日挑战赛#OpenHarmony资源管理详解-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-7-5 09:58:30修改
5
收藏 1
回复
举报
3条回复
按时间正序
/
按时间倒序
鸿蒙坚果派
鸿蒙坚果派

我在开头提的rawfile目录描述有误得到了回复,确实是官方文档有瑕疵,我已经提Pr,等待审查结束就可以看到了

回复
2022-7-5 10:34:58
程序员小阿杰
程序员小阿杰

资源管理是应用开发的第一步,感谢楼主

回复
2022-7-5 14:05:46
程序员法医
程序员法医

大佬写的很好,受益匪浅,nice

回复
2022-7-21 21:16:17
回复
    相关推荐