文章目录
- 背景
- 方法总览
- 为什么要用资源文件?
- getResourceManager():获取资源管理器
- 读取字符串资源:三种方式
- 三种方式怎么选?
- 读取数字资源
- tryLog 辅助方法的设计技巧
- 写在最后
背景
近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦
案例demo导航展示
↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
做 HarmonyOS 应用,你肯定见过代码里的$r('app.string.app_name')这种写法。这是在引用资源文件里定义的字符串。但怎么在代码里动态读取这些资源值?这就是ResUtil干的事。
方法总览
为什么要用资源文件?
硬编码字符串(直接在代码里写"我的应用")有几个问题:
- 不支持多语言:换语言就得改代码
- 维护麻烦:同一段文字在多个地方用,改的时候漏改
- 设计规范问题:颜色、尺寸值散落各处,风格不统一
正确做法是把这些值定义在resources/目录下的 JSON 文件里,代码里通过$r()引用。资源文件支持按语言分目录,实现自动多语言切换。
getResourceManager():获取资源管理器
ResUtil.getResourceManager()返回系统的ResourceManager实例,是所有资源操作的基础。
this.Btn('getResourceManager() 获取资源管理器','#4A90E2',()=>{constrm=ResUtil.getResourceManager();this.addLog(`getResourceManager() → [ResourceManager] ok=${!!rm}`);})实际运行结果:
getResourceManager()→[ResourceManager] ok=true
通常你不需要直接用ResourceManager,ResUtil的其他方法已经封装好了常用操作。但如果需要调用一些ResUtil没封装的底层方法,可以通过getResourceManager()拿到原始对象再操作。
读取字符串资源:三种方式
HarmonyOS 资源文件里定义的字符串类似这样(resources/base/element/string.json):
{"string":[{"name":"app_name","value":"HoUtils"}]}读取这个字符串有三种方式:
方式一:getStringSync(同步,用$r引用)
this.Btn('getStringSync($r("app.string.app_name"))','#27AE60',()=>{this.tryLog('getStringSync($r("app.string.app_name"))',()=>ResUtil.getStringSync($r('app.string.app_name')));})$r('app.string.app_name')是 ArkTS 的资源引用语法,app表示当前应用,string是资源类型,app_name是资源名。
方式二:getStringByNameSync(同步,用资源名字符串)
this.Btn('getStringByNameSync(resName)','#1E8449',()=>{this.tryLog(`getStringByNameSync("${this.resName}")`,()=>ResUtil.getStringByNameSync(this.resName));})这种方式传的是资源名的字符串(比如"app_name"),适合需要动态指定资源名的场景。
方式三:getStringValue(异步,Promise 风格)
this.Btn('getStringValue($r("app.string.app_name")) async','#148F77',()=>{ResUtil.getStringValue($r('app.string.app_name')).then(v=>{this.addLog(`getStringValue($r("app.string.app_name")) → "${v}"`);}).catch((e:Error)=>{this.addLog(`getStringValue Error:${e.message}`);});})还有对应的getStringByName异步版本:
this.Btn('getStringByName("app_name") async','#117A65',()=>{ResUtil.getStringByName('app_name').then(v=>{this.addLog(`getStringByName("app_name") → "${v}"`);}).catch((e:Error)=>{this.addLog(`Error:${e.message}`);});})三种方式怎么选?
| 方式 | 特点 | 适合场景 |
|---|---|---|
getStringSync($r(...)) | 同步,编译期检查资源是否存在 | 常规使用,资源名固定 |
getStringByNameSync(name) | 同步,运行时动态指定资源名 | 根据条件动态读取不同资源 |
getStringValue($r(...)) | 异步,不阻塞 UI | 性能敏感场景,或需要批量加载 |
getStringByName(name) | 异步+动态名 | 需要异步 + 动态资源名 |
大多数情况下,getStringSync($r(...))就够用了,简单直接。
读取数字资源
除了字符串,资源文件里还可以定义数字(float):
this.Btn('getNumber($r("app.float.logo_image_size"))','#E67E22',()=>{this.tryLog('getNumber($r("app.float.logo_image_size"))',()=>ResUtil.getNumber($r('app.float.logo_image_size')).toString());})资源文件里定义的浮点数(尺寸、比例等)通过getNumber读取,返回数值类型,可以直接用于布局计算。
tryLog 辅助方法的设计技巧
Demo 里有个tryLog辅助方法,值得学一下:
privatetryLog(label:string,fn:()=>string){try{constresult=fn();this.addLog(`${label}→${result}`);}catch(e){this.addLog(`${label}→ [Error]${e}`);}}它接受一个标签和一个返回字符串的函数,统一处理成功和失败的日志输出。这种设计让调用处代码很简洁,不用每个按钮都写try/catch。这是封装错误处理逻辑的好实践。
写在最后
资源管理是 HarmonyOS 开发的基础功能,特别是你想做多语言支持的话,把字符串放资源文件里是必选项。ResUtil把各种读取方式都封装好了,直接用就行。
下一篇讲颜色和图片媒体资源的读取,以及设备配置查询。