EzResources

宿主资源替换。hook Resources / TypedArray 的 getter,按「包名 + 类型 + 名称」拦截取值。 直接值不注入 APK;模块资源兼容入口通过 ResourcesLoader 绑定宿主资源池。思路来自 HyperCeiler 的 ResourcesTool。

EzResources.setResReplacement("com.miui.home", "drawable", "ic_launcher", R.drawable.my_icon)
EzResources.setObjectReplacement("com.miui.home", "color", "bg", Color.RED)
EzResources.setDensityReplacement("com.miui.home", "dimen", "bar_height", 8f)

包名传 "*" 表示不限宿主,精确匹配优先。hook 按需装、进程级、带稳定 reloadKey,模块不需要持有或摘除。 替换规则按名字存、取值时才对当前挂着的 apk 解析 id,所以 102 热重载换 apk 不会串资源;loader 由新一代先挂新再摘旧。

Functions

Link copied to clipboard

清掉全部替换规则;不卸载 getter hook,也不撤销 inject 创建的资源绑定。

Link copied to clipboard

兼容用的名称 hash 标识;可能冲突,不会创建 Android 资源,也不能保证宿主能解析。

Link copied to clipboard
fun inject(context: Context, onMainLooper: Boolean = false): Boolean

inject 的 Context 形式。

fun inject(resources: Resources, onMainLooper: Boolean = false): Boolean

把模块 apk 挂进 resources,之后宿主能解析模块的 R.xxx。R 及以上走 ResourcesLoader,否则回退 AssetManager.addAssetPath。重复调用同一个 resources 是安全的。

Link copied to clipboard
fun setDensityReplacement(pkg: String, type: String, name: String, value: Float)

数值 x 屏幕密度,即 dp 语义。用于 dimen。

Link copied to clipboard
fun setObjectReplacement(pkg: String, type: String, name: String, value: Any)

直接给一个值。类型要和取值方法对得上(getText 需要 CharSequence,数值类接受任意 Number), 对不上会记一条 warn 并放行原值。数组在登记和返回时复制,其它对象的内部可变状态由调用者负责。

Link copied to clipboard
fun setResReplacement(pkg: String, type: String, name: String, moduleResId: Int)

用模块里的资源顶掉宿主资源。