mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 17:55:24 +08:00
Added ModuleApplication function and merge findClass function to Xposed API
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
> 你或许可能会遇到浏览器缓存造成文档不是最新版本的问题,若已经查看过一次文档,请手动在每个页面上刷新,以获取最新版本或清除浏览器缓存。
|
> 你或许可能会遇到浏览器缓存造成文档不是最新版本的问题,若已经查看过一次文档,请手动在每个页面上刷新,以获取最新版本或清除浏览器缓存。
|
||||||
|
|
||||||
最新版本更新时间:2022-04-13 13:57
|
最新版本更新时间:2022-04-15 04:30
|
||||||
|
|
||||||
## Contacts
|
## Contacts
|
||||||
|
|
||||||
@@ -49,6 +49,11 @@
|
|||||||
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
|
- 工作不易,无意外情况此项目将继续维护下去,提供更多可能,欢迎打赏。<br/><br/>
|
||||||
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg" width = "200" height = "200"/>
|
<img src="https://github.com/fankes/YuKiHookAPI/blob/master/img-src/wechat_code.jpg" width = "200" height = "200"/>
|
||||||
|
|
||||||
|
## Third-Party Open Source Usage Statement
|
||||||
|
|
||||||
|
- [Kotlin Symbol Processing API](https://github.com/google/ksp)
|
||||||
|
- [FreeReflection](https://github.com/tiann/FreeReflection)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
- [MIT](https://choosealicense.com/licenses/mit)
|
- [MIT](https://choosealicense.com/licenses/mit)
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
package="com.highcapable.yukihookapi.demo_module">
|
package="com.highcapable.yukihookapi.demo_module">
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".application.DemoApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_icon"
|
android:icon="@mipmap/ic_icon"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* YukiHookAPI - An efficient Kotlin version of the Xposed Hook API.
|
||||||
|
* Copyright (C) 2019-2022 HighCapable
|
||||||
|
* https://github.com/fankes/YukiHookAPI
|
||||||
|
*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is Created by fankes on 2022/4/15.
|
||||||
|
*/
|
||||||
|
package com.highcapable.yukihookapi.demo_module.application
|
||||||
|
|
||||||
|
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||||
|
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication
|
||||||
|
|
||||||
|
class DemoApplication : ModuleApplication() {
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
loggerD(msg = "I am running in module space")
|
||||||
|
}
|
||||||
|
}
|
@@ -45,7 +45,8 @@ class HookEntry : YukiHookXposedInitProxy {
|
|||||||
// 可简写为 configs {}
|
// 可简写为 configs {}
|
||||||
YukiHookAPI.configs {
|
YukiHookAPI.configs {
|
||||||
// 全局调试用的 TAG
|
// 全局调试用的 TAG
|
||||||
debugTag = "YukiHookAPI"
|
// 在 Logcat 控制台过滤此 TAG 可找到详细日志
|
||||||
|
debugTag = "YukiHookAPI-Demo"
|
||||||
// 是否开启调试模式
|
// 是否开启调试模式
|
||||||
isDebug = true
|
isDebug = true
|
||||||
// 是否启用调试日志的输出功能
|
// 是否启用调试日志的输出功能
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
- 方便移植 快速上手
|
- 方便移植 快速上手
|
||||||
|
|
||||||
<font size=3 style="opacity: 0.6">`更新时间 2022-04-13 13:57`</font>
|
<font size=3 style="opacity: 0.6">`更新时间 2022-04-15 04:30`</font>
|
||||||
|
|
||||||
[GitHub](https://github.com/fankes/YukiHookAPI)
|
[GitHub](https://github.com/fankes/YukiHookAPI)
|
||||||
[Get Started](#介绍)
|
[Get Started](#介绍)
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
[filename](public/PrefsData.md ':include')
|
[filename](public/PrefsData.md ':include')
|
||||||
|
|
||||||
|
[filename](public/ModuleApplication.md ':include')
|
||||||
|
|
||||||
[filename](public/ComponentTypeFactory.md ':include')
|
[filename](public/ComponentTypeFactory.md ':include')
|
||||||
|
|
||||||
[filename](public/GraphicsTypeFactory.md ':include')
|
[filename](public/GraphicsTypeFactory.md ':include')
|
||||||
|
76
docs/api/public/ModuleApplication.md
Normal file
76
docs/api/public/ModuleApplication.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
## ModuleApplication [class]
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
open class ModuleApplication: Application()
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>变更记录</b>
|
||||||
|
|
||||||
|
`v1.0.76` `新增`
|
||||||
|
|
||||||
|
<b>功能描述</b>
|
||||||
|
|
||||||
|
> 这是对使用 `YukiHookAPI` Xposed 模块实现中的一个扩展功能。
|
||||||
|
|
||||||
|
在你的 Xposed 模块的 `Application` 中继承此类。
|
||||||
|
|
||||||
|
或在 `AndroidManifest.xml` 的 `application` 标签中指定此类。
|
||||||
|
|
||||||
|
目前可实现功能如下
|
||||||
|
|
||||||
|
- 全局共享模块中静态的 `appContext`
|
||||||
|
|
||||||
|
- 在模块与宿主中装载 `YukiHookAPI.Config` 以确保 `YukiHookAPI.Configs.debugTag` 不需要重复定义
|
||||||
|
|
||||||
|
- 在模块中使用系统隐藏 API,核心技术引用了开源项目 [FreeReflection](https://github.com/tiann/FreeReflection)
|
||||||
|
|
||||||
|
<b>功能示例</b>
|
||||||
|
|
||||||
|
将此类继承到你的自定义 `Application` 上。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
package com.demo
|
||||||
|
|
||||||
|
class MyApplication: ModuleApplication() {
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `AndroidManifest.xml` 的 `application` 标签中指定自定义的 `Application`。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<application
|
||||||
|
android:name="com.demo.MyApplication"
|
||||||
|
...>
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你不需要自定义 `Application` 可以直接将 `ModuleApplication` 设置到 `AndroidManifest.xml` 的 `application` 标签中。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<application
|
||||||
|
android:name="com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication"
|
||||||
|
...>
|
||||||
|
```
|
||||||
|
|
||||||
|
### appContext [field]
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val appContext: ModuleApplication
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>变更记录</b>
|
||||||
|
|
||||||
|
`v1.0.76` `新增`
|
||||||
|
|
||||||
|
<b>功能描述</b>
|
||||||
|
|
||||||
|
> 全局静态 `Application` 实例。
|
@@ -355,6 +355,23 @@ method {
|
|||||||
|
|
||||||
> 这些异常会直接导致 APP 停止运行(FC),同时会在控制台打印 `E` 级别的日志,还会造成 Hook 进程“死掉”。
|
> 这些异常会直接导致 APP 停止运行(FC),同时会在控制台打印 `E` 级别的日志,还会造成 Hook 进程“死掉”。
|
||||||
|
|
||||||
|
!> `IllegalStateException` App is dead, You cannot call to appContext
|
||||||
|
|
||||||
|
<b>异常原因</b>
|
||||||
|
|
||||||
|
使用 `ModuleApplication` 时调用了 `appContext` 功能但是 APP 可能已经被销毁或没有正确启动。
|
||||||
|
|
||||||
|
> 示例如下
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
// 调用了此变量但是 APP 可能已被销毁或没有正确启动
|
||||||
|
ModuleApplication.appContext
|
||||||
|
```
|
||||||
|
|
||||||
|
<b>解决方案</b>
|
||||||
|
|
||||||
|
这种情况基本不存在,由于 `appContext` 是在 `onCreate` 中被赋值的,除非遇到多进程并发启动或 APP 没有启动完成前被反射调用了父类的 `onCreate` 方法。
|
||||||
|
|
||||||
!> `IllegalStateException` YukiHookModulePrefs not allowed in Custom Hook API
|
!> `IllegalStateException` YukiHookModulePrefs not allowed in Custom Hook API
|
||||||
|
|
||||||
<b>异常原因</b>
|
<b>异常原因</b>
|
||||||
|
@@ -104,6 +104,10 @@ class MainHook : YukiHookXposedInitProxy {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
你还可以将你的模块 APP 的 `Application` 继承于 `ModuleApplication` 以实现更多功能。
|
||||||
|
|
||||||
|
详情请参考 [ModuleApplication](api/document?id=moduleapplication-class)。
|
||||||
|
|
||||||
然后,你就可以开始编写 Hook 代码了。
|
然后,你就可以开始编写 Hook 代码了。
|
||||||
|
|
||||||
有关作为 Xposed 模块使用的相关配置详细内容,你可以 [点击这里](config/xposed-using) 继续阅读。
|
有关作为 Xposed 模块使用的相关配置详细内容,你可以 [点击这里](config/xposed-using) 继续阅读。
|
||||||
|
@@ -211,9 +211,49 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
packageName.split(".hook")[0]
|
packageName.split(".hook")[0]
|
||||||
else error(msg = "Cannot identify your App's package name, please manually configure the package name")
|
else error(msg = "Cannot identify your App's package name, please manually configure the package name")
|
||||||
}
|
}
|
||||||
|
val injectPackageName = "com.highcapable.yukihookapi.hook.xposed.application.inject"
|
||||||
|
fun commentContent(name: String) = ("/**\n" +
|
||||||
|
" * $name Inject Class\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Compiled from YukiHookXposedProcessor\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * HookEntryClass: [$className]\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Generate Date: ${SimpleDateFormat.getDateTimeInstance().format(Date())}\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Powered by YukiHookAPI (C) HighCapable 2022\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Project Address: [YukiHookAPI](https://github.com/fankes/YukiHookAPI)\n" +
|
||||||
|
" */\n")
|
||||||
codeGenerator.createNewFile(
|
codeGenerator.createNewFile(
|
||||||
Dependencies.ALL_FILES,
|
dependencies = Dependencies.ALL_FILES,
|
||||||
packageName,
|
packageName = injectPackageName,
|
||||||
|
fileName = "ModuleApplication_Injector"
|
||||||
|
).apply {
|
||||||
|
/** 插入 ModuleApplication_Injector 代码 */
|
||||||
|
write(
|
||||||
|
("@file:Suppress(\"ClassName\")\n" +
|
||||||
|
"\n" +
|
||||||
|
"package $injectPackageName\n" +
|
||||||
|
"\n" +
|
||||||
|
"import $packageName.$className\n" +
|
||||||
|
"\n" +
|
||||||
|
commentContent(name = "ModuleApplication") +
|
||||||
|
"object ModuleApplication_Injector {\n" +
|
||||||
|
"\n" +
|
||||||
|
" @JvmStatic\n" +
|
||||||
|
" fun callApiInit() = try {\n" +
|
||||||
|
" $className().onInit()\n" +
|
||||||
|
" } catch (_: Throwable) {\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}").toByteArray()
|
||||||
|
)
|
||||||
|
flush()
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
codeGenerator.createNewFile(
|
||||||
|
dependencies = Dependencies.ALL_FILES,
|
||||||
|
packageName = packageName,
|
||||||
fileName = "$className$xposedClassShortName"
|
fileName = "$className$xposedClassShortName"
|
||||||
).apply {
|
).apply {
|
||||||
/** 插入 xposed_init 代码 */
|
/** 插入 xposed_init 代码 */
|
||||||
@@ -232,19 +272,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
||||||
"import $packageName.$className\n" +
|
"import $packageName.$className\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"/**\n" +
|
commentContent(name = "XposedInit") +
|
||||||
" * XposedInit Inject Class\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Compiled from YukiHookXposedProcessor\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * HookEntryClass: [$className]\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Generate Date: ${SimpleDateFormat.getDateTimeInstance().format(Date())}\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Powered by YukiHookAPI (C) HighCapable 2022\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Project Address: https://github.com/fankes/YukiHookAPI\n" +
|
|
||||||
" */\n" +
|
|
||||||
"@Keep\n" +
|
"@Keep\n" +
|
||||||
"@YukiGenerateApi\n" +
|
"@YukiGenerateApi\n" +
|
||||||
"class $className$xposedClassShortName : IXposedHookLoadPackage {\n" +
|
"class $className$xposedClassShortName : IXposedHookLoadPackage {\n" +
|
||||||
|
@@ -40,7 +40,8 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// Used 82 API Version
|
// Used 82 API Version
|
||||||
compileOnly 'de.robv.android.xposed:api:82'
|
compileOnly 'de.robv.android.xposed:api:82'
|
||||||
compileOnly fileTree(include: ['android-stub.jar'], dir: 'libs')
|
compileOnly fileTree(include: ['android-stub.jar', 'module-injector.jar'], dir: 'libs')
|
||||||
|
implementation fileTree(include: ['free-reflection.jar'], dir: 'libs')
|
||||||
implementation 'androidx.annotation:annotation:1.3.0'
|
implementation 'androidx.annotation:annotation:1.3.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
yukihookapi/libs/free-reflection.jar
Normal file
BIN
yukihookapi/libs/free-reflection.jar
Normal file
Binary file not shown.
BIN
yukihookapi/libs/module-injector.jar
Normal file
BIN
yukihookapi/libs/module-injector.jar
Normal file
Binary file not shown.
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.factory
|
package com.highcapable.yukihookapi.hook.factory
|
||||||
|
|
||||||
|
import com.highcapable.yukihookapi.YukiHookAPI
|
||||||
import com.highcapable.yukihookapi.hook.bean.CurrentClass
|
import com.highcapable.yukihookapi.hook.bean.CurrentClass
|
||||||
import com.highcapable.yukihookapi.hook.bean.HookClass
|
import com.highcapable.yukihookapi.hook.bean.HookClass
|
||||||
import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
|
import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
|
||||||
@@ -36,6 +37,7 @@ import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
|
|||||||
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
|
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
|
||||||
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
|
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
|
||||||
import com.highcapable.yukihookapi.hook.store.MemberCacheStore
|
import com.highcapable.yukihookapi.hook.store.MemberCacheStore
|
||||||
|
import de.robv.android.xposed.XposedHelpers
|
||||||
import java.lang.reflect.Constructor
|
import java.lang.reflect.Constructor
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Member
|
import java.lang.reflect.Member
|
||||||
@@ -71,8 +73,16 @@ val String.hasClass get() = hasClass(loader = null)
|
|||||||
fun classOf(name: String, loader: ClassLoader? = null): Class<*> {
|
fun classOf(name: String, loader: ClassLoader? = null): Class<*> {
|
||||||
val hashCode = ("[$name][$loader]").hashCode()
|
val hashCode = ("[$name][$loader]").hashCode()
|
||||||
return MemberCacheStore.findClass(hashCode) ?: run {
|
return MemberCacheStore.findClass(hashCode) ?: run {
|
||||||
(if (loader == null) Class.forName(name)
|
when {
|
||||||
else loader.loadClass(name)).also { MemberCacheStore.putClass(hashCode, it) }
|
YukiHookAPI.hasXposedBridge ->
|
||||||
|
runCatching { XposedHelpers.findClassIfExists(name, loader) }.getOrNull()
|
||||||
|
?: when (loader) {
|
||||||
|
null -> Class.forName(name)
|
||||||
|
else -> loader.loadClass(name)
|
||||||
|
}
|
||||||
|
loader == null -> Class.forName(name)
|
||||||
|
else -> loader.loadClass(name)
|
||||||
|
}.also { MemberCacheStore.putClass(hashCode, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* YukiHookAPI - An efficient Kotlin version of the Xposed Hook API.
|
||||||
|
* Copyright (C) 2019-2022 HighCapable
|
||||||
|
* https://github.com/fankes/YukiHookAPI
|
||||||
|
*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is Created by fankes on 2022/4/15.
|
||||||
|
*/
|
||||||
|
package com.highcapable.yukihookapi.hook.xposed.application
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import com.highcapable.yukihookapi.YukiHookAPI
|
||||||
|
import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext
|
||||||
|
import com.highcapable.yukihookapi.hook.xposed.application.inject.ModuleApplication_Injector
|
||||||
|
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||||
|
import me.weishu.reflection.Reflection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这是对使用 [YukiHookAPI] Xposed 模块实现中的一个扩展功能
|
||||||
|
*
|
||||||
|
* 在你的 Xposed 模块的 [Application] 中继承此类
|
||||||
|
*
|
||||||
|
* 或在 AndroidManifest.xml 的 application 标签中指定此类
|
||||||
|
*
|
||||||
|
* 目前可实现功能如下
|
||||||
|
*
|
||||||
|
* - 全局共享模块中静态的 [appContext]
|
||||||
|
*
|
||||||
|
* - 在模块与宿主中装载 [YukiHookAPI.Configs] 以确保 [YukiHookAPI.Configs.debugTag] 不需要重复定义
|
||||||
|
*
|
||||||
|
* - 在模块中使用系统隐藏 API - 核心技术引用了开源项目 [FreeReflection](https://github.com/tiann/FreeReflection)
|
||||||
|
*
|
||||||
|
* 详情请参考 [ModuleApplication](https://fankes.github.io/YukiHookAPI/#/api/document?id=moduleapplication-class)
|
||||||
|
*/
|
||||||
|
open class ModuleApplication : Application() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
/** 全局静态 [Application] 实例 */
|
||||||
|
private var currentContext: ModuleApplication? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局静态 [Application] 实例
|
||||||
|
* @throws IllegalStateException 如果 [Application] 没有正确装载完成
|
||||||
|
*/
|
||||||
|
val appContext get() = currentContext ?: error("App is dead, You cannot call to appContext")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context?) {
|
||||||
|
super.attachBaseContext(base)
|
||||||
|
Reflection.unseal(base)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
currentContext = this
|
||||||
|
callApiInit()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 调用入口类的 [YukiHookXposedInitProxy.onInit] 方法 */
|
||||||
|
private fun callApiInit() = runCatching { ModuleApplication_Injector.callApiInit() }
|
||||||
|
}
|
Reference in New Issue
Block a user