HarmonyOS鸿蒙Next中资源在打包后为什么id会被替换成-1
HarmonyOS鸿蒙Next中资源在打包后为什么id会被替换成-1 通过$r(‘app.string.xxxx’)引入资源,在打包后,为什么id会被替换成-1
原始代码:

打包后查看js文件:

这个导致诸如
this.getUIContext().getHostContext()?.resourceManager.getNumber($r(‘app.integer.xxxx’).id)
等方法无法在打包后正常使用
更多关于HarmonyOS鸿蒙Next中资源在打包后为什么id会被替换成-1的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者你好,我这边项目在进行编译的时候,并不会出现id为-1的情况,辛苦提供一下你这边的IDE版本信息,我这边进一步分析。
示例如下:
{ "id": 16777311, "type": 10003, params: [], "bundleName": "com.aaa.xxx", "moduleName": "entry" }
更多关于HarmonyOS鸿蒙Next中资源在打包后为什么id会被替换成-1的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
把这个useNormalizedOHMUrl设置为true,在编译期暴露错误。
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
这个其实是 HarmonyOS 资源系统的一个“运行时资源对象”机制,不是资源真的丢了。
你看到:
$r('app.string.xxx')
打包后变成:
{
id: -1,
type: xxxx,
params: [...]
}
这是因为:
HarmonyOS NEXT 在:
HAR/HSP
动态资源
跨包资源
场景下,
很多 $r() 返回的已经不是:
静态编译期资源ID
而是:
Resource对象(懒加载资源引用)
所以:
id = -1
代表:
当前资源没有固定编译期resId
不是异常。
⸻
因此:
你这种写法:
resourceManager.getNumber($r('app.integer.xxx').id)
本身就不可靠。
因为:
$r()
现在不一定有真实 id。
⸻
尤其:
HarmonyOS 5+
Stage模型
HAR组件化
以后:
越来越多资源会变成动态Resource
而不是 Android 那种:
R.xxx.xxx 固定int id
⸻
正确写法(推荐)
不要依赖 .id
改成:
resourceManager.getNumberByName(...)
或者:
resourceManager.getStringByName(...)
例如:
const rm = this.getUIContext().getHostContext()?.resourceManager
let value = rm?.getNumberByName('app.integer.xxx')
这是官方更推荐的方式。
⸻
或者:
直接使用 Resource:
很多组件本身支持:
Resource
直接传:
Text($r('app.string.xxx'))
不要自己取 id。
⸻
为什么 Debug 可能正常,Release 出问题?
因为:
Debug 下:
可能保留本地资源映射
Release / HAR 后:
资源会重新编译
资源ID压缩
动态资源化
所以:
id=-1
更容易出现。
⸻
尤其你这种:
HAR包
HSP
组件库
场景,
最容易出现:
Resource.id = -1
因为资源可能根本不在当前 module。
⸻
一句话总结:
HarmonyOS NEXT 中 $r() 返回的很多已经是动态 Resource 对象,不再保证存在固定 resId,因此打包后 id=-1 是正常现象。不要再依赖 .id 去调用 resourceManager.getXXX(),应改用 getXXXByName() 或直接传递 $r() Resource 对象。
确认下是不是开启了混淆,如果开启,关掉配置中的混淆,重新打包试试~
在模块build-profile.json5配置文件中的arkOptions.obfuscation.ruleOptions字段中,通过enable字段配置是否开启混淆。
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": false, // 关闭混淆开关。
"files": ["./obfuscation-rules.txt"] // 指定配置混淆规则文件, 在编译本模块时生效。
},
// ...
}
},
相关文档:
👍,
id变包后变成-1是因为编译器开启了混淆,要在obfuscation-rules.txt下新增配置
# 保留 ResourceTable 类中的所有字段
-keep class .*.ResourceTable {
public <fields>;
}
# 保留所有使用 @Entry 注解的类
-keep class **.view.** {
<methods>;
}
在HarmonyOS Next中,资源打包后ID被替换为-1,是因为资源编译阶段,资源索引表被重新生成,未正确注册的资源ID会被置为无效值(-1)。常见原因包括:资源文件路径或命名违反规范、资源未在resources目录下正确配置、或使用了不支持的资源类型。打包工具无法映射该资源时,即分配-1。
在 HarmonyOS NEXT 正式打包(如 Release 模式)时,编译器会启用资源 ID 压缩/混淆优化。此时 $r() 返回的 Resource 对象中的 id 字段会被统一标记为 -1,表示该 ID 不再具有直接映射到具体资源的意义,这是为了减小包体并防止反编译通过 ID 直接访问资源。
代码里 $r('app.integer.xxxx').id 因此拿到 -1,传递给 resourceManager.getNumber() 自然失败。
正确做法是直接传递整个 Resource 对象给 resourceManager API,例如 getNumber($r('app.integer.xxxx')),引擎内部会使用 Resource 中的 bundleName/moduleName 和资源名称进行解析,而非依赖打包后的 id。

