# PackageParam - class | Yuki Hook API
一个使用 Kotlin 重构的轻量、高效、稳定的 Xposed Hook API

# # PackageParam - class

    open class PackageParam internal constructor(internal var wrapper: PackageParamWrapper?)

变更记录

`v1.0` `添加`

功能描述

> 装载 Hook 的目标 APP 入口对象实现类。

## # appClassLoader - field

    val appClassLoader：ClassLoader

变更记录

`v1.0` `添加`

功能描述

> 获取当前 Hook APP 的 `ClassLoader`。

## # appInfo - field

    val appInfo: ApplicationInfo

变更记录

`v1.0` `添加`

功能描述

> 获取当前 Hook APP 的 `ApplicationInfo`。

## # appUserId - field

    val appUserId: Int

变更记录

`v1.1.0` `新增`

功能描述

> 获取当前 Hook APP 的用户 ID。

机主为 `0`，应用双开 (分身) 或工作资料因系统环境不同 ID 也各不相同。

## # appContext - field

    val appContext: Application?

变更记录

`v1.0.72` `新增`

`v1.1.0` `修改`

加入可空类型 (空安全)

功能描述

> 获取当前 Hook APP 的 `Application`。

特别注意

首次装载可能是空的，请延迟一段时间再获取或使用 onAppLifecycle 监听来完成。

## # appResources - field

    val appResources：Resources?

变更记录

`v1.0.80` `新增`

`v1.1.0` `修改`

加入可空类型 (空安全)

功能描述

> 获取当前 Hook APP 的 Resources。

特别注意

你只能在 HookResources.hook 方法体内或 appContext 装载完毕时进行调用。

## # systemContext - field

    val systemContext: Context

变更记录

`v1.1.0` `新增`

功能描述

> 获取当前系统框架的 `Context`。

## # processName - field

    val processName: String

变更记录

`v1.0` `添加`

功能描述

> 获取当前 Hook APP 的进程名称。

## # packageName - field

    val packageName: String

变更记录

`v1.0` `添加`

功能描述

> 获取当前 Hook APP 的包名。

## # isFirstApplication - field

    val isFirstApplication: Boolean

变更记录

`v1.0` `添加`

功能描述

> 获取当前 Hook APP 是否为第一个 `Application`。

## # mainProcessName - field

    val mainProcessName: String

变更记录

`v1.0.70` `新增`

功能描述

> 获取当前 Hook APP 的主进程名称。

其对应的就是 `packageName`。

## # moduleAppFilePath - field

    val moduleAppFilePath: String

变更记录

`v1.0.80` `新增`

功能描述

> 获取当前 Xposed 模块自身 APK 文件路径。

特别注意

作为 Hook API 装载时无法使用，会获取到空字符串。

## # moduleAppResources - field

    val moduleAppResources: YukiModuleResources

变更记录

`v1.0.80` `新增`

功能描述

> 获取当前 Xposed 模块自身 `Resources`。

特别注意

作为 Hook API 或不支持的 Hook Framework 装载时无法使用，会抛出异常。

## # prefs - field

    val prefs: YukiHookModulePrefs

变更记录

`v1.0` `添加`

功能描述

> 获得当前使用的存取数据对象缓存实例。

特别注意

作为 Hook API 装载时无法使用，会抛出异常。

## # prefs - method

    fun prefs(name: String): YukiHookModulePrefs

变更记录

`v1.0` `添加`

`v1.0.80` `修改`

将方法体进行 inline

功能描述

> 获得当前使用的存取数据对象缓存实例。

你可以通过 `name` 来自定义 Sp 存储的名称。

特别注意

作为 Hook API 装载时无法使用，会抛出异常。

## # dataChannel - field

    val dataChannel: YukiHookDataChannel.NameSpace

变更记录

`v1.0.88` `新增`

功能描述

> 获得当前使用的数据通讯桥命名空间对象。

特别注意

作为 Hook API 装载时无法使用，会抛出异常。

## # resources - method

    fun resources(): HookResources

变更记录

`v1.0.80` `新增`

功能描述

> 获得当前 Hook APP 的 `YukiResources` 对象。

请调用 `HookResources.hook` 方法开始 Hook。

## # refreshModuleAppResources - method

    fun refreshModuleAppResources()

变更记录

`v1.0.87` `新增`

功能描述

> 刷新当前 Xposed 模块自身 `Resources`。

## # onAppLifecycle - method

    inline fun onAppLifecycle(initiate: AppLifecycle.() -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 生命周期装载事件。

注意

在 loadZygote 中不会被装载，仅会在 loadSystem、loadApp 中装载。

作为 Hook API 装载时请使用原生的 Application 实现生命周期监听。

## # loadApp - method

    inline fun loadApp(name: String, initiate: PackageParam.() -> Unit)

    fun loadApp(name: String, hooker: YukiBaseHooker)

变更记录

`v1.0` `添加`

`v1.0.80` `修改`

将方法体进行 inline

功能描述

> 装载并 Hook 指定包名的 APP。

`name` 为 APP 的包名，后方的两个参数一个可作为 `lambda` 方法体使用，一个可以直接装载子 Hooker。

装载并 Hook 指定、全部包名的 APP。

若要装载 APP Zygote 事件，请使用 `loadZygote`。

若要 Hook 系统框架，请使用 `loadSystem`。

功能示例

你可以使用 `loadApp` 的 `lambda` 方法体形式或直接装载一个 Hooker。

> 示例如下

    // 使用 lambda
    loadApp(name = "com.example.test") {
        // Your code here.
    }
    // 使用 Hooker
    loadApp(name = "com.example.test", CustomHooker)

若不指定 `name` 参数，则此方法体默认会过滤当前系统中全部可被 Hook 的 APP。

> 示例如下

    // 使用 lambda
    loadApp {
        // Your code here.
    }
    // 使用 Hooker
    loadApp(hooker = CustomHooker)

## # loadZygote - method

    inline fun loadZygote(initiate: PackageParam.() -> Unit)

    fun loadZygote(hooker: YukiBaseHooker)

变更记录

`v1.0.80` `新增`

功能描述

> 装载 APP Zygote 事件。

方法中的两个参数一个可作为 `lambda` 方法体使用，一个可以直接装载子 Hooker。

## # loadSystem - method

    inline fun loadSystem(initiate: PackageParam.() -> Unit)

    fun loadSystem(hooker: YukiBaseHooker)

变更记录

`v1.0.82` `新增`

功能描述

> 装载并 Hook 系统框架。

方法中的两个参数一个可作为 `lambda` 方法体使用，一个可以直接装载子 Hooker。

## # withProcess - method

    inline fun withProcess(name: String, initiate: PackageParam.() -> Unit)

    fun withProcess(name: String, hooker: YukiBaseHooker)

变更记录

`v1.0.70` `新增`

功能描述

> 装载并 Hook APP 的指定进程。

`name` 为 APP 的进程名称，后方的两个参数一个可作为 `lambda` 方法体使用，一个可以直接装载子 Hooker。

## # loadHooker - method

    fun loadHooker(hooker: YukiBaseHooker)

变更记录

`v1.0` `添加`

功能描述

> 装载 Hook 子类。

你可以填入 `hooker` 在 Hooker 中继续装载 Hooker。

## # searchClass - method

    inline fun searchClass(name: String, async: Boolean, initiate: ClassConditions): DexClassFinder.Result

变更记录

`v1.1.0` `新增`

功能描述

> 通过 `appClassLoader` 按指定条件查找并得到当前 Hook APP Dex 中的 `Class`。

特别注意

此方法在 Class 数量过多及查找条件复杂时会非常耗时。

建议启用 async 或设置 name 参数，name 参数将在 Hook APP (宿主) 不同版本中自动进行本地缓存以提升效率。

此功能尚在试验阶段，性能与稳定性可能仍然存在问题，使用过程遇到问题请向我们报告并帮助我们改进。

## String+VariousClass.clazz - i-ext-field

变更记录

`v1.0` `添加`

`v1.1.0` `作废`

请转移到 `toClass(...)` 方法

## String.hasClass - i-ext-field

变更记录

`v1.0` `添加`

`v1.1.0` `作废`

请转移到 `hasClass(...)` 方法

## # String+VariousClass.toClass - i-ext-method

    fun String.toClass(loader: ClassLoader?): Class<*>

    fun VariousClass.toClass(loader: ClassLoader?): Class<*>

变更记录

`v1.1.0` `新增`

功能描述

> 通过字符串类名、`VariousClass` 转换为 `loader` 中的实体类。

默认使用当前 `appClassLoader` 装载目标 `Class`。

功能示例

你可以轻松地将 `String` 类型的 `Class` 包名转为 `Class` 实例。

> 示例如下

    "com.example.demo.DemoClass".toClass()

你还可以向 `loader` 参数传入你自定义的 `ClassLoader`。

> 示例如下

    val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoader
    "com.example.demo.DemoClass".toClass(customClassLoader)

你还可以创建一个 `VariousClass`，并转换为实体类。

`VariousClass` 会枚举所有设置的 `Class` 并最终获得第一个存在的 `Class`。

> 示例如下

    VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").toClass()

同样地，你还可以向 `loader` 参数传入你自定义的 `ClassLoader`。

> 示例如下

    val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoader
    VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").toClass(customClassLoader)

## # String+VariousClass.toClassOrNull - i-ext-method

    fun String.toClassOrNull(loader: ClassLoader?): Class<*>?

    fun VariousClass.toClassOrNull(loader: ClassLoader?): Class<*>?

变更记录

`v1.1.0` `新增`

功能描述

> 通过字符串类名、`VariousClass` 转换为 `loader` 中的实体类。

默认使用当前 `appClassLoader` 装载目标 `Class`。

找不到 `Class` 会返回 `null`，不会抛出异常。

功能示例

用法请参考 String+VariousClass.toClass 方法。

## # String.hasClass - i-ext-method

    fun String.hasClass(loader: ClassLoader?): Boolean

变更记录

`v1.1.0` `新增`

功能描述

> 通过字符串类名查找是否存在。

默认使用当前 `appClassLoader` 装载目标 `Class`。

功能示例

你可以轻松的使用此方法判断字符串中的类是否存在。

> 示例如下

    if("com.example.demo.DemoClass".hasClass()) {
        // Your code here.
    }

你还可以自定义其中的 `loader` 参数，默认为 `appClassLoader`。

> 示例如下

    val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoader
    if("com.example.demo.DemoClass".hasClass(customClassLoader)) {
        // Your code here.
    }

## # findClass - method

    fun findClass(name: String, loader: ClassLoader?): HookClass

    fun findClass(vararg name: String, loader: ClassLoader?): VariousClass

变更记录

`v1.0` `添加`

`v1.0.1` `修改`

移除了 `findClass(various: VariousClass)` 方法

`v1.1.0` `修改`

新增 `loader` 参数

功能描述

> 通过完整包名+名称查找需要被 Hook 的 `Class`。

注意

使用此方法会得到一个 HookClass 仅用于 Hook，若想查找 Class 请使用 toClass 功能。

功能示例

你可以使用三种方式查找你需要 Hook 的目标 `Class`。

你可以直接将被查找的 `Class` 完整包名+名称填入 `name` 中。

> 示例如下

    findClass(name = "com.example.demo.DemoClass")

若你不确定多个版本的 `Class` 以及不同名称，你可以将多个完整包名+名称填入 `name` 中。

> 示例如下

    findClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2", "com.example.demo.DemoClass3")

你还可以创建一个 `VariousClass`，将 `Class` 的完整包名+名称填入 `VariousClass` 的 `name` 中并填入 `various` 参数中。

> 示例如下

    val variousClass = VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2", "com.example.demo.DemoClass3")

若你当前需要查找的 `Class` 不属于 `appClassLoader`，你可以使用 `loader` 参数指定你要装载的 `ClassLoader`。

> 示例如下

    val outsideLoader: ClassLoader? = ... // 假设这就是你的 ClassLoader
    findClass(name = "com.example.demo.OutsideClass", loader = outsideLoader)

同样地，在不确定多个版本的 `Class` 以及不同名称时，也可以使用 `loader` 参数指定你要装载的 `ClassLoader`。

> 示例如下

    val outsideLoader: ClassLoader? = ... // 假设这就是你的 ClassLoader
    findClass("com.example.demo.OutsideClass1", "com.example.demo.OutsideClass2", "com.example.demo.OutsideClass3", loader = outsideLoader)

## # String+Class+VariousClass+HookClass.hook - i-ext-method

    inline fun String.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result

    inline fun Class<*>.hook(isForceUseAbsolute: Boolean, initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result

    inline fun VariousClass.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result

    inline fun HookClass.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result

变更记录

`v1.0` `添加`

`v1.0.1` `修改`

新增 `VariousClass` 的直接调用 `hook` 方法

`v1.0.2` `修改`

新增 `String` 的直接调用 `hook` 方法

`v1.0.3` `修改`

新增 `YukiMemberHookCreator.Result` 返回值

`v1.0.70` `修改`

新增 `isUseAppClassLoader` 参数

`v1.0.80` `修改`

将方法体进行 inline

`v1.1.0` `修改`

移除了 `isUseAppClassLoader` 参数

添加了 `isForceUseAbsolute` 参数到 `Class.hook` 方法

功能描述

> 这是一切 Hook 的入口创建方法，Hook 方法、构造方法。

功能示例

如你所见，Hook 方法体的创建可使用 4 种方式。

通过字符串类名得到 `HookClass` 实例进行创建。

> 示例如下

    "com.example.demo.DemoClass".hook {
        // Your code here.
    }

通过 `findClass` 得到 `HookClass` 实例进行创建。

> 示例如下

    findClass(name = "com.example.demo.DemoClass").hook {
        // Your code here.
    }

使用 `stub` 或直接拿到 `Class` 实例进行创建。

默认情况下 API 会将 `Class` 实例转换为类名并绑定到 `appClassLoader`，若失败，则会使用原始 `Class` 实例直接进行 Hook。

> 示例如下

    Stub::class.java.hook {
        // Your code here.
    }

若当前 `Class` 不在 `appClassLoader` 且自动匹配无法找到该 `Class`，请启用 `isForceUseAbsolute`。

> 示例如下

    YourClass::class.java.hook(isForceUseAbsolute = true) {
        // Your code here.
    }

使用 `VariousClass` 实例进行创建。

> 示例如下

    VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").hook {
        // Your code here.
    }

或者直接使用可变字符串数组进行创建。

> 示例如下

    findClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").hook {
        // Your code here.
    }

## # HookResources.hook - i-ext-method

    inline fun HookResources.hook(initiate: YukiResourcesHookCreator.() -> Unit)

变更记录

`v1.0.80` `新增`

功能描述

> Hook APP 的 Resources。

特别注意

请注意你需要确保当前 Hook Framework 支持且 InjectYukiHookWithXposed.isUsingResourcesHook 已启用。

功能示例

Resources Hook 为固定用法，获取 `resources` 对象，然后调用 `hook` 方法开始 Hook。

> 示例如下

    resources().hook {
        // Your code here.
    }

特别注意

这是固定用法，为了防止发生问题，你不可手动实现任何 HookResources 实例执行 hook 调用。

将 Resources 的 Hook 设置为这样是为了与 `findClass(...).hook` 做到统一，使得调用起来逻辑不会混乱。

## # AppLifecycle - class

    inner class AppLifecycle internal constructor()

变更记录

`v1.0.88` `新增`

功能描述

> 当前 Hook APP 的生命周期实例处理类。

### # attachBaseContext - method

    fun attachBaseContext(result: (baseContext: Context, hasCalledSuper: Boolean) -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 装载 `Application.attachBaseContext`。

### # onCreate - method

    fun onCreate(initiate: Application.() -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 装载 `Application.onCreate`。

### # onTerminate - method

    fun onTerminate(initiate: Application.() -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 装载 `Application.onTerminate`。

### # onLowMemory - method

    fun onLowMemory(initiate: Application.() -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 装载 `Application.onLowMemory`。

### # onTrimMemory - method

    fun onTrimMemory(result: (self: Application, level: Int) -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 装载 `Application.onTrimMemory`。

### # onConfigurationChanged - method

    fun onConfigurationChanged(result: (self: Application, config: Configuration) -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 监听当前 Hook APP 装载 `Application.onConfigurationChanged`。

### # registerReceiver - method

    fun registerReceiver(vararg action: String, result: (context: Context, intent: Intent) -> Unit)

变更记录

`v1.0.88` `新增`

功能描述

> 注册系统广播监听。