资源ID重定向后,findById
等直接基于资源ID的调用需根据资源隔离机制调整调用方式,以下为具体场景及调用示例:
一、资源ID重定向原理
资源ID重定向通过修改资源编译后的PP段
(Package ID Prefix)实现宿主与插件资源隔离,例如:
- 宿主资源ID :
0x7f010000
(默认值) - 插件资源ID :
0x5f010000
(重定向后)67
二、调用方式调整示例
1. 插件内部调用(无需修改)
若资源ID重定向仅在编译阶段完成 且插件内部资源引用使用R类常量,则无需修改代码:
perl
// 插件内直接使用R.id.xxx
View button = findViewById(R.id.btn_submit); // 自动指向0x5f前缀的ID :ml-citation{ref="6" data="citationList"}
2. 宿主调用插件资源(需动态获取ID)
宿主需通过资源名+包名动态获取插件资源ID:
ini
// 宿主获取插件资源ID
String pluginPackage = "com.plugin.demo";
int pluginBtnId = getResources().getIdentifier(
"btn_submit", "id", pluginPackage // 动态解析为0x5f前缀的ID
);
View pluginButton = findViewById(pluginBtnId); // 正确访问插件资源 :ml-citation{ref="3,6" data="citationList"}
3. 跨插件资源调用(需显式隔离)
插件A调用插件B的资源时,需通过插件B的Context访问资源:
ini
// 插件A获取插件B的Context
Context pluginBContext = RePlugin.createPackageContext("com.plugin.b", 0);
// 动态获取插件B的资源ID
int pluginBResId = pluginBContext.getResources().getIdentifier(
"btn_confirm", "id", "com.plugin.b"
);
View pluginBButton = pluginBContext.findViewById(pluginBResId); // 隔离访问 :ml-citation{ref="6,7" data="citationList"}
三、关键注意事项
-
资源命名规范
宿主与插件资源命名需添加前缀隔离 (如
host_
/pluginA_
),避免同名资源因PP段不同导致逻辑混淆67。 -
资源动态加载
使用
AssetManager.addAssetPath()
动态加载插件资源路径时,需确保新生成的Resources
实例已包含重定向后的ID映射:iniAssetManager assets = getAssets(); assets.addAssetPath(pluginApkPath); // 加载插件资源 Resources pluginRes = new Resources(assets, getDisplayMetrics(), getConfiguration()); int resId = pluginRes.getIdentifier("btn_ok", "id", pluginPackage); // 正确解析ID :ml-citation{ref="6" data="citationList"}
-
资源冲突检测
使用
aapt dump resources
检查宿主与插件的resources.arsc
文件,确认PP段无重叠67。
四、适配方案对比
场景 | 适配方式 | 优点 | 缺点 |
---|---|---|---|
插件内部调用 | 直接使用R类常量 | 无需改造代码 | 仅限插件内部使用 |
宿主调用插件资源 | 动态获取资源ID | 灵活跨组件访问 | 需维护包名与资源名映射 |
跨插件调用 | 通过目标插件Context访问 | 严格隔离资源空间 | 需显式传递插件上下文 |
通过上述调整,资源ID重定向后findById
等调用可正确访问目标资源,同时避免宿主与插件间的资源冲突