作为 Xposed 模块使用的相关配置
这里介绍了
YukiHookAPI
作为 Xposed 模块使用的相关配置方法。
依赖配置
作为 Xposed 模块,
YukiHookAPI
提供了一个自动处理程序。
你需要在你的构建脚本中集成 com.highcapable.yukihookapi:ksp-xposed
依赖的最新版本。
自定义处理程序
你可以对
YukiHookAPI
将如何生成xposed_init
入口进行相关配置。
InjectYukiHookWithXposed 注解
annotation class InjectYukiHookWithXposed(
val sourcePath: String,
val modulePackageName: String,
val entryClassName: String,
val isUsingXposedModuleStatus: Boolean,
val isUsingResourcesHook: Boolean
)
@InjectYukiHookWithXposed
注解是一个标记模块 Hook 入口的重要注解。
特别注意
@InjectYukiHookWithXposed 注解的 Class 必须实现 IYukiHookXposedInit 接口。
在你当前项目中的所有 Class 标记中只能存在一次,若存在多个声明自动处理程序会在编译时抛出异常,你可以自定义其相关参数。
sourcePath 参数
sourcePath
参数决定了自动处理程序自动查找并匹配你当前项目路径的重要标识,此参数的内容为相对路径匹配,默认参数为 src/main
。
特别注意
如果你的项目不在 ../src/main.. 或你手动使用 sourceSets 设置了项目路径,你就需要手动设置 sourcePath 参数,否则自动处理程序将无法识别你的项目路径并会在编译时抛出异常。
示例如下
@InjectYukiHookWithXposed(sourcePath = "src/custom")
sourcePath
使用的文件路径分隔符写法根据 Windows
和 Unix
将自动进行识别,使用 /
或 \
均可。
modulePackageName 参数
modulePackageName
是你当前项目的 applicationId
,也就是你的模块包名 (最终生成的应用包名),留空或不填时自动处理程序将对当前项目文件进行分析并生成。
注意
若你想使用模块包名自动生成,你需要确保你的项目命名空间在 AndroidManifest.xml、build.gradle 或 build.gradle.kts 中存在如下任意定义方式。
特别注意
在 Android Gradle Plugin 8+ 版本中,你需要手动在项目的 build.gradle 或 build.gradle.kts 中启用 buildConfig。
Groovy DSL
android {
buildFeatures {
buildConfig true
}
}
Kotlin DSL
android {
buildFeatures {
buildConfig = true
}
}
示例命名空间 com.example.demo
,以下定义方式任选其一。
以下定义方式仅供参考,通常情况下只要你的项目能够正常生成 BuildConfig.java
文件,就不需要做额外操作。
AndroidManifest.xml
示例
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo">
build.gradle
示例
android {
namespace 'com.example.demo'
}
build.gradle.kts
示例
android {
namespace = "com.example.demo"
}
若你的模块包名是非常规手段进行自动生成的,或你认为有必要手动定义模块包名,那么你可以直接设置 modulePackageName
的参数。
示例如下
@InjectYukiHookWithXposed(modulePackageName = "com.example.demo")
特别注意
请不要在 modulePackageName 中填写 BuildConfig.APPLICATION_ID,这会在编译过程中获取到空字符串,这取决于 Android Gradle Plugin 的行为。
只要你自定义了 modulePackageName
的参数,你就会在编译时收到警告。
示例如下
You set the customize module package name to "com.example.demo", please check for yourself if it is correct
注意
手动定义的模块包名除了格式之外,自动处理程序将不会再检查模块包名是否正确,需要你自行确认其有效性。
entryClassName 参数
entryClassName
决定了自动处理程序如何生成 xposed_init
中的入口类名,默认会使用你的入口类包名插入 _YukiHookXposedInit
后缀进行生成。
假设这是你的入口类。
示例如下
@InjectYukiHookWithXposed
object HookEntry : IYukiHookXposedInit
Xposed 入口类处理如下。
示例如下
class HookEntry_YukiHookXposedInit : IXposedHookZygoteInit, IXposedHookLoadPackage, ...
编译后的类名结构如下。
示例如下
...hook.HookEntry ← 你的入口类
...hook.HookEntry_Impl ← 自动生成的 Impl 类
...hook.HookEntry_YukiHookXposedInit ← 自动生成的 Xposed 入口类
我们现在定义入口类名称为 HookXposedEntry
。
示例如下
@InjectYukiHookWithXposed(entryClassName = "HookXposedEntry")
object HookEntry : IYukiHookXposedInit
Xposed 入口类处理如下。
示例如下
class HookXposedEntry : IXposedHookZygoteInit, IXposedHookLoadPackage, ...
编译后的类名结构如下。
示例如下
...hook.HookEntry ← 你的入口类
...hook.HookEntry_Impl ← 自动生成的 Impl 类
...hook.HookXposedEntry ← 自动生成的 Xposed 入口类
小提示
入口类可以使用 class 或 object 定义,但是建议使用 object 定义来保证每一个注入的进程都是单例运行。
特别注意
你定义的 entryClassName 不可与 xposed_init 中的类名相同,否则自动处理程序会在编译时抛出异常。
isUsingXposedModuleStatus 参数
isUsingXposedModuleStatus
决定了自动处理程序是否生成针对 Xposed 模块激活等状态功能的相关代码,此功能默认启用。
生成后你将可以在模块进程中使用 YukiHookAPI.Status
的相关功能。
如果你不希望生成相关代码,你可以手动关闭此功能,仅对模块进程生效。
isUsingResourcesHook 参数
isUsingResourcesHook
决定了自动处理程序是否生成针对 Resources Hook 的相关代码,此功能默认不启用。
默认情况下生成的入口类将为如下所示。
示例如下
class _YukiHookXposedInit : IXposedHookZygoteInit, IXposedHookLoadPackage {
override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam?) {
// ...
}
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
// ...
}
}
若你当前的项目需要用到 Resources Hook,可以设置 isUsingResourcesHook = true
来启用自动生成。
注意
此功能在 1.2.0 版本后将不再默认启用,如需使用请手动启用。
示例如下
@InjectYukiHookWithXposed(isUsingResourcesHook = true)
启用后生成的入口类将为如下所示。
示例如下
class _YukiHookXposedInit : IXposedHookZygoteInit, IXposedHookLoadPackage, IXposedHookInitPackageResources {
override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam?) {
// ...
}
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
// ...
}
override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {
// ...
}
}
小提示
由于 Xposed 入口类是被 YukiHookAPI 动态生成的,它会同时生成如下两个文件。
assets/xposed_init
resources/META-INF/yukihookapi_init
如果你正在使用 Git 代码控制系统,你可以将这两个文件添加到 .gitignore 文件中。
IYukiHookXposedInit 接口
IYukiHookXposedInit
接口为你的 Hook 入口类必须实现的接口,这是你的模块开始 Hook 的起点。
小提示
更多功能请参考 IYukiHookXposedInit。
当你的模块被 Xposed 装载后,onHook
方法将会被回调,你需要在此方法中开始使用 YukiHookAPI
。
基本的调用流程为
_YukiHookXposedInit
→IYukiHookXposedInit.onXposedEvent
→IYukiHookXposedInit.onInit
→IYukiHookXposedInit.onHook
详情请参考 API 基本配置。
原生 Xposed API 事件
若你当前的 Xposed 模块使用了第三方的资源,但是短时间内可能无法转移它们,此时,你可以使用 onXposedEvent
实现监听原生 Xposed API 的全部装载事件。
示例如下
@InjectYukiHookWithXposed
object HookEntry : IYukiHookXposedInit {
override fun onHook() {
// Your code here.
}
override fun onXposedEvent() {
// 监听原生 Xposed API 的装载事件
YukiXposedEvent.events {
onInitZygote {
// it 对象即 [StartupParam]
}
onHandleLoadPackage {
// it 对象即 [LoadPackageParam]
}
onHandleInitPackageResources {
// it 对象即 [InitPackageResourcesParam]
}
}
}
}
onXposedEvent
与 onHook
方法完全独立存在,互不影响,你可以继续在 onHook
方法中使用 YukiHookAPI
。
小提示
更多功能请参考 IYukiHookXposedInit.onXposedEvent 方法。