mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-06 02:35:40 +08:00
Added excludeHostClasses, excludeModuleClasses function in ModuleClassLoader
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
* This file is Created by fankes on 2022/8/8.
|
||||
* Thanks for providing https://github.com/cinit/QAuxiliary/blob/main/app/src/main/java/io/github/qauxv/lifecycle/Parasitics.java
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.highcapable.yukihookapi.hook.xposed.parasitic.reference
|
||||
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
||||
@@ -35,26 +37,64 @@ import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
||||
/**
|
||||
* 自动处理 (Xposed) 宿主环境与模块环境的 [ClassLoader]
|
||||
*/
|
||||
internal class ModuleClassLoader private constructor() : ClassLoader(AppParasitics.baseClassLoader) {
|
||||
class ModuleClassLoader private constructor() : ClassLoader(AppParasitics.baseClassLoader) {
|
||||
|
||||
internal companion object {
|
||||
companion object {
|
||||
|
||||
/** 当前 [ModuleClassLoader] 单例 */
|
||||
private var instance: ModuleClassLoader? = null
|
||||
|
||||
/** 排除的 Hook APP (宿主) [Class] 类名数组 */
|
||||
private val excludeHostClasses = HashSet<String>()
|
||||
|
||||
/** 排除的模块 [Class] 类名数组 */
|
||||
private val excludeModuleClasses = HashSet<String>()
|
||||
|
||||
/**
|
||||
* 获取 [ModuleClassLoader] 单例
|
||||
* @return [ModuleClassLoader]
|
||||
*/
|
||||
internal fun instance() = instance ?: ModuleClassLoader().apply { instance = this }
|
||||
|
||||
/**
|
||||
* 添加到 Hook APP (宿主) [Class] 排除列表
|
||||
*
|
||||
* 排除列表中的 [Class] 将会使用宿主的 [ClassLoader] 进行装载
|
||||
*
|
||||
* - ❗排除列表仅会在 (Xposed) 宿主环境生效
|
||||
* @param name 需要添加的 [Class] 完整类名
|
||||
*/
|
||||
fun excludeHostClasses(vararg name: String) {
|
||||
excludeHostClasses.addAll(name.toList())
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加到模块 [Class] 排除列表
|
||||
*
|
||||
* 排除列表中的 [Class] 将会使用模块 (当前宿主环境的模块注入进程) 的 [ClassLoader] 进行装载
|
||||
*
|
||||
* - ❗排除列表仅会在 (Xposed) 宿主环境生效
|
||||
* @param name 需要添加的 [Class] 完整类名
|
||||
*/
|
||||
fun excludeModuleClasses(vararg name: String) {
|
||||
excludeModuleClasses.addAll(name.toList())
|
||||
}
|
||||
|
||||
init {
|
||||
excludeHostClasses.add("androidx.lifecycle.ReportFragment")
|
||||
}
|
||||
}
|
||||
|
||||
/** 默认 [ClassLoader] */
|
||||
private val baseLoader get() = AppParasitics.baseClassLoader
|
||||
|
||||
override fun loadClass(name: String, resolve: Boolean): Class<*> {
|
||||
if (YukiHookBridge.hasXposedBridge.not()) return AppParasitics.baseClassLoader.loadClass(name)
|
||||
return YukiHookAppHelper.currentApplication()?.classLoader?.let { loader ->
|
||||
runCatching { if (name == "androidx.lifecycle.ReportFragment") return@let loader.loadClass(name) }
|
||||
runCatching { return@let AppParasitics.baseClassLoader.loadClass(name) }
|
||||
runCatching { AppParasitics.baseClassLoader.loadClass(name) }.getOrNull() ?: loader.loadClass(name)
|
||||
if (YukiHookBridge.hasXposedBridge.not()) return baseLoader.loadClass(name)
|
||||
return YukiHookAppHelper.currentApplication()?.classLoader?.let { hostLoader ->
|
||||
excludeHostClasses.takeIf { it.isNotEmpty() }?.forEach { runCatching { if (name == it) return@let hostLoader.loadClass(name) } }
|
||||
excludeModuleClasses.takeIf { it.isNotEmpty() }?.forEach { runCatching { if (name == it) return@let baseLoader.loadClass(name) } }
|
||||
runCatching { return@let baseLoader.loadClass(name) }
|
||||
runCatching { baseLoader.loadClass(name) }.getOrNull() ?: hostLoader.loadClass(name)
|
||||
} ?: super.loadClass(name, resolve)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user