最近折腾了一下Xposed在目标APP中注入模块自己的资源

因为Xposed模块是运行在目标App的环境, 而不是模块自己的App环境中的, 因此不能访问模块自己的资源, 会找不到

使用 XModuleResources 进行资源注入要挨个资源去处理, 需要自己管理fakeId, 模块资源一多就过于繁琐 (麻烦的要死.webp

研究了一下如何直接将整个模块的资源注入到目标APP中, 以R.xxx的方式直接调用

实现

首先实现 IXposedHookZygoteInit , 保存 modulePath 后续使用

@Override
public void initZygote(StartupParam startupParam) {
    modulePath = startupParam.modulePath;
}

在模块加载到目标APP (IXposedHookLoadPackage 或者随便别的什么花活方式)

获取到目标APP的 Context 后, 调用 AssetManager.addAssetPath 将模块资源添加到目标APP的资源搜索路径

XposedHelpers.callMethod(context.getResources().getAssets(), "addAssetPath", modulePath);

为避免模块资源ID与目标App的资源ID冲突, 在 build.gradleandroid 节下添加如下参数手动指定 package-id

android {
    aaptOptions {
        additionalParameters '--allow-reserved-package-id', '--package-id', '0x65'
    }
}

效果

直接使用R.xxx调资源就行了, 和普通Android APP的开发一模一样

LayoutInflater.from(contextOfTargetApp).inflate(R.layout.layout_in_your_module, null);