Merge code to inline method, improve execution efficiency

This commit is contained in:
2022-04-25 02:37:22 +08:00
parent 44c3401831
commit 4131772c12
24 changed files with 418 additions and 181 deletions

View File

@@ -33,8 +33,13 @@ kotlin {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
jvmTarget = 11
freeCompilerArgs += "-opt-in=com.highcapable.yukihookapi.annotation.YukiPrivateApi"
freeCompilerArgs += "-opt-in=com.highcapable.yukihookapi.annotation.YukiGenerateApi"
freeCompilerArgs = [
'-opt-in=com.highcapable.yukihookapi.annotation.YukiPrivateApi',
'-opt-in=com.highcapable.yukihookapi.annotation.YukiGenerateApi',
'-Xno-param-assertions',
'-Xno-call-assertions',
'-Xno-receiver-assertions'
]
}
}

View File

@@ -160,7 +160,8 @@ object YukiHookAPI {
var isEnableMemberCache = true
/** 结束方法体 */
internal fun build() {}
@PublishedApi
internal fun build() = Unit
}
/**
@@ -176,7 +177,7 @@ object YukiHookAPI {
* 详情请参考 [configs 方法](https://fankes.github.io/YukiHookAPI/#/config/api-example?id=configs-%e6%96%b9%e6%b3%95)
* @param initiate 方法体
*/
fun configs(initiate: Configs.() -> Unit) = Configs.apply(initiate).build()
inline fun configs(initiate: Configs.() -> Unit) = Configs.apply(initiate).build()
/**
* 作为模块装载调用入口方法 - Xposed API

View File

@@ -54,22 +54,24 @@ import java.lang.reflect.Member
* @param packageParam 需要传入 [PackageParam] 实现方法调用
* @param hookClass 要 Hook 的 [HookClass] 实例
*/
class YukiHookCreater(private val packageParam: PackageParam, private val hookClass: HookClass) {
class YukiHookCreater(private val packageParam: PackageParam, @PublishedApi internal val hookClass: HookClass) {
/**
* Hook 模式定义
*/
enum class HookMemberMode { HOOK_ALL_METHODS, HOOK_ALL_CONSTRUCTORS, HOOK_CONVENTIONAL }
/** 是否对当前 [YukiHookCreater] 禁止执行 Hook 操作 */
private var isDisableCreaterRunHook = false
/** 设置要 Hook 的方法、构造类 */
private var hookMembers = HashSet<MemberHookCreater>()
/** [hookClass] 找不到时出现的错误回调 */
private var onHookClassNotFoundFailureCallback: ((Throwable) -> Unit)? = null
/** 是否对当前 [YukiHookCreater] 禁止执行 Hook 操作 */
@PublishedApi
internal var isDisableCreaterRunHook = false
/** 设置要 Hook 的方法、构造类 */
@PublishedApi
internal var hookMembers = HashSet<MemberHookCreater>()
/**
* 得到当前被 Hook 的 [Class]
*
@@ -86,7 +88,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [MemberHookCreater.Result]
*/
fun injectMember(tag: String = "Default", initiate: MemberHookCreater.() -> Unit) =
inline fun injectMember(tag: String = "Default", initiate: MemberHookCreater.() -> Unit) =
MemberHookCreater(tag).apply(initiate).apply { hookMembers.add(this) }.build()
/**
@@ -132,9 +134,12 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
/** [afterHook] 回调 */
private var afterHookCallback: (HookParam.() -> Unit)? = null
/** [replaceAny]、[replaceUnit]、[replaceTo] 等回调 */
/** [replaceAny]、[replaceUnit] 回调 */
private var replaceHookCallback: (HookParam.() -> Any?)? = null
/** [replaceTo]、[replaceToTrue]、[replaceToFalse]、[intercept] 的值 */
private var replaceHookResult: Any? = null
/** Hook 成功时回调 */
private var onHookedCallback: ((Member) -> Unit)? = null
@@ -150,20 +155,27 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
/** 全部错误回调 */
private var onAllFailureCallback: ((Throwable) -> Unit)? = null
/** 查找过程中发生的异常 */
private var findingThrowable: Throwable? = null
/** 是否为替换 Hook 模式 */
private var isReplaceHookMode = false
/** 标识是否已经设置了要 Hook 的 [member] */
private var isHookMemberSetup = false
/** 是否为仅替换 Hook 结果模式 */
private var isReplaceHookOnlyResultMode = false
/** 是否对当前 [MemberHookCreater] 禁止执行 Hook 操作 */
private var isDisableMemberRunHook = false
@PublishedApi
internal var isDisableMemberRunHook = false
/** 查找过程中发生的异常 */
@PublishedApi
internal var findingThrowable: Throwable? = null
/** 标识是否已经设置了要 Hook 的 [member] */
@PublishedApi
internal var isHookMemberSetup = false
/** Hook 当前模式类型 */
private var hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
@PublishedApi
internal var hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
/** 全部方法的名称 */
private var allMethodsName = ""
@@ -219,7 +231,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [MethodFinder.Result]
*/
fun method(initiate: MethodFinder.() -> Unit) = try {
inline fun method(initiate: MethodFinder.() -> Unit) = try {
hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
isHookMemberSetup = true
MethodFinder(hookInstance = this, hookClass.instance).apply(initiate).build(isBind = true)
@@ -237,7 +249,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [ConstructorFinder.Result]
*/
fun constructor(initiate: ConstructorFinder.() -> Unit = {}) = try {
inline fun constructor(initiate: ConstructorFinder.() -> Unit = {}) = try {
hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
isHookMemberSetup = true
ConstructorFinder(hookInstance = this, hookClass.instance).apply(initiate).build(isBind = true)
@@ -251,7 +263,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [FieldFinder.Result]
*/
fun HookParam.field(initiate: FieldFinder.() -> Unit) =
inline fun HookParam.field(initiate: FieldFinder.() -> Unit) =
if (hookClass.instance == null) FieldFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable)
else FieldFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build()
@@ -260,7 +272,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [MethodFinder.Result]
*/
fun HookParam.method(initiate: MethodFinder.() -> Unit) =
inline fun HookParam.method(initiate: MethodFinder.() -> Unit) =
if (hookClass.instance == null) MethodFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable)
else MethodFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build()
@@ -269,7 +281,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [ConstructorFinder.Result]
*/
fun HookParam.constructor(initiate: ConstructorFinder.() -> Unit) =
inline fun HookParam.constructor(initiate: ConstructorFinder.() -> Unit) =
if (hookClass.instance == null) ConstructorFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable)
else ConstructorFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build()
@@ -303,6 +315,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
*/
fun replaceAny(initiate: HookParam.() -> Any?) {
isReplaceHookMode = true
isReplaceHookOnlyResultMode = false
replaceHookCallback = initiate
}
@@ -314,6 +327,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
*/
fun replaceUnit(initiate: HookParam.() -> Unit) {
isReplaceHookMode = true
isReplaceHookOnlyResultMode = false
replaceHookCallback = initiate
}
@@ -325,7 +339,8 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
*/
fun replaceTo(any: Any?) {
isReplaceHookMode = true
replaceHookCallback = { any }
isReplaceHookOnlyResultMode = true
replaceHookResult = any
}
/**
@@ -337,7 +352,8 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
*/
fun replaceToTrue() {
isReplaceHookMode = true
replaceHookCallback = { true }
isReplaceHookOnlyResultMode = true
replaceHookResult = true
}
/**
@@ -349,7 +365,8 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
*/
fun replaceToFalse() {
isReplaceHookMode = true
replaceHookCallback = { false }
isReplaceHookOnlyResultMode = true
replaceHookResult = false
}
/**
@@ -361,7 +378,8 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
*/
fun intercept() {
isReplaceHookMode = true
replaceHookCallback = { null }
isReplaceHookOnlyResultMode = true
replaceHookResult = null
}
/**
@@ -395,9 +413,9 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
if (baseParam == null) return null
return HookParam(createrInstance = this@YukiHookCreater, HookParamWrapper(baseParam)).let { param ->
try {
if (replaceHookCallback != null)
if (replaceHookCallback != null || isReplaceHookOnlyResultMode)
onHookLogMsg(msg = "Replace Hook Member [${member ?: "All Member $allMethodsName"}] done [$tag]")
replaceHookCallback?.invoke(param)
if (isReplaceHookOnlyResultMode) replaceHookResult else replaceHookCallback?.invoke(param)
} catch (e: Throwable) {
onConductFailureCallback?.invoke(param, e)
onAllFailureCallback?.invoke(e)
@@ -542,7 +560,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun result(initiate: Result.() -> Unit) = apply(initiate)
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 添加执行 Hook 需要满足的条件
@@ -551,7 +569,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 条件方法体
* @return [Result] 可继续向下监听
*/
fun by(initiate: () -> Boolean): Result {
inline fun by(initiate: () -> Boolean): Result {
isDisableMemberRunHook = (runCatching { initiate() }.getOrNull() ?: false).not()
if (isDisableMemberRunHook) ignoredAllFailure()
return this
@@ -650,7 +668,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun result(initiate: Result.() -> Unit) = apply(initiate)
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 添加执行 Hook 需要满足的条件
@@ -659,7 +677,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
* @param initiate 条件方法体
* @return [Result] 可继续向下监听
*/
fun by(initiate: () -> Boolean): Result {
inline fun by(initiate: () -> Boolean): Result {
isDisableCreaterRunHook = (runCatching { initiate() }.getOrNull() ?: false).not()
return this
}

View File

@@ -48,7 +48,9 @@ import java.lang.reflect.Constructor
* @param classSet 当前需要查找的 [Class] 实例
*/
class ConstructorFinder(
@property:YukiPrivateApi
override val hookInstance: YukiHookCreater.MemberHookCreater? = null,
@property:YukiPrivateApi
override val classSet: Class<*>? = null
) : BaseFinder(tag = "Constructor", hookInstance, classSet) {
@@ -62,7 +64,8 @@ class ConstructorFinder(
private var paramTypes: Array<out Class<*>>? = null
/** [ModifierRules] 实例 */
private var modifiers: ModifierRules? = null
@PublishedApi
internal var modifiers: ModifierRules? = null
/**
* 设置 [Constructor] 参数个数
@@ -80,7 +83,7 @@ class ConstructorFinder(
* @param initiate 方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition {
inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition {
modifiers = ModifierRules().apply(initiate)
return IndexTypeCondition(IndexConfigType.MATCH)
}
@@ -188,7 +191,8 @@ class ConstructorFinder(
inner class RemedyPlan {
/** 失败尝试次数数组 */
private val remedyPlans = HashSet<Pair<ConstructorFinder, Result>>()
@PublishedApi
internal val remedyPlans = HashSet<Pair<ConstructorFinder, Result>>()
/**
* 创建需要重新查找的 [Constructor]
@@ -198,7 +202,7 @@ class ConstructorFinder(
* 若最后依然失败 - 将停止查找并输出错误日志
* @param initiate 方法体
*/
fun constructor(initiate: ConstructorFinder.() -> Unit) =
inline fun constructor(initiate: ConstructorFinder.() -> Unit) =
Result().apply { remedyPlans.add(Pair(ConstructorFinder(hookInstance, classSet).apply(initiate), this)) }
/**
@@ -206,6 +210,7 @@ class ConstructorFinder(
*
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
*/
@PublishedApi
@YukiPrivateApi
internal fun build() {
if (classSet == null) return
@@ -265,14 +270,14 @@ class ConstructorFinder(
* @param isNoSuch 是否没有找到构造方法 - 默认否
* @param e 错误信息
*/
inner class Result(internal val isNoSuch: Boolean = false, private val e: Throwable? = null) {
inner class Result(@PublishedApi internal val isNoSuch: Boolean = false, @PublishedApi internal val e: Throwable? = null) {
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun result(initiate: Result.() -> Unit) = apply(initiate)
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 获得 [Constructor] 实例处理类
@@ -312,7 +317,7 @@ class ConstructorFinder(
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun remedys(initiate: RemedyPlan.() -> Unit): Result {
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result {
isUsingRemedyPlan = true
if (isNoSuch) RemedyPlan().apply(initiate).build()
return this
@@ -325,7 +330,7 @@ class ConstructorFinder(
* @param initiate 回调错误
* @return [Result] 可继续向下监听
*/
fun onNoSuchConstructor(initiate: (Throwable) -> Unit): Result {
inline fun onNoSuchConstructor(initiate: (Throwable) -> Unit): Result {
if (isNoSuch) initiate(e ?: Throwable())
return this
}

View File

@@ -47,12 +47,15 @@ import java.lang.reflect.Field
* @param classSet 当前需要查找的 [Class] 实例
*/
class FieldFinder(
@property:YukiPrivateApi
override val hookInstance: YukiHookCreater.MemberHookCreater? = null,
@property:YukiPrivateApi
override val classSet: Class<*>? = null
) : BaseFinder(tag = "Field", hookInstance, classSet) {
/** [ModifierRules] 实例 */
private var modifiers: ModifierRules? = null
@PublishedApi
internal var modifiers: ModifierRules? = null
/**
* 设置 [Field] 名称
@@ -79,7 +82,7 @@ class FieldFinder(
* @param initiate 方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition {
inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition {
modifiers = ModifierRules().apply(initiate)
return IndexTypeCondition(IndexConfigType.MATCH)
}
@@ -159,14 +162,14 @@ class FieldFinder(
* @param isNoSuch 是否没有找到变量 - 默认否
* @param e 错误信息
*/
inner class Result(internal val isNoSuch: Boolean = false, private val e: Throwable? = null) {
inner class Result(@PublishedApi internal val isNoSuch: Boolean = false, private val e: Throwable? = null) {
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun result(initiate: Result.() -> Unit) = apply(initiate)
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 得到变量实例处理类

View File

@@ -48,7 +48,9 @@ import java.lang.reflect.Method
* @param classSet 当前需要查找的 [Class] 实例
*/
class MethodFinder(
@property:YukiPrivateApi
override val hookInstance: YukiHookCreater.MemberHookCreater? = null,
@property:YukiPrivateApi
override val classSet: Class<*>? = null
) : BaseFinder(tag = "Method", hookInstance, classSet) {
@@ -62,7 +64,8 @@ class MethodFinder(
private var paramTypes: Array<out Class<*>>? = null
/** [ModifierRules] 实例 */
private var modifiers: ModifierRules? = null
@PublishedApi
internal var modifiers: ModifierRules? = null
/**
* 设置 [Method] 名称
@@ -98,7 +101,7 @@ class MethodFinder(
* @param initiate 方法体
* @return [BaseFinder.IndexTypeCondition]
*/
fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition {
inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition {
modifiers = ModifierRules().apply(initiate)
return IndexTypeCondition(IndexConfigType.MATCH)
}
@@ -236,7 +239,8 @@ class MethodFinder(
inner class RemedyPlan {
/** 失败尝试次数数组 */
private val remedyPlans = HashSet<Pair<MethodFinder, Result>>()
@PublishedApi
internal val remedyPlans = HashSet<Pair<MethodFinder, Result>>()
/**
* 创建需要重新查找的 [Method]
@@ -247,7 +251,7 @@ class MethodFinder(
* @param initiate 方法体
* @return [Result] 结果
*/
fun method(initiate: MethodFinder.() -> Unit) =
inline fun method(initiate: MethodFinder.() -> Unit) =
Result().apply { remedyPlans.add(Pair(MethodFinder(hookInstance, classSet).apply(initiate), this)) }
/**
@@ -255,6 +259,7 @@ class MethodFinder(
*
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
*/
@PublishedApi
@YukiPrivateApi
internal fun build() {
if (classSet == null) return
@@ -314,14 +319,14 @@ class MethodFinder(
* @param isNoSuch 是否没有找到方法 - 默认否
* @param e 错误信息
*/
inner class Result(internal val isNoSuch: Boolean = false, private val e: Throwable? = null) {
inner class Result(@PublishedApi internal val isNoSuch: Boolean = false, @PublishedApi internal val e: Throwable? = null) {
/**
* 创建监听结果事件方法体
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun result(initiate: Result.() -> Unit) = apply(initiate)
inline fun result(initiate: Result.() -> Unit) = apply(initiate)
/**
* 获得 [Method] 实例处理类
@@ -365,7 +370,7 @@ class MethodFinder(
* @param initiate 方法体
* @return [Result] 可继续向下监听
*/
fun remedys(initiate: RemedyPlan.() -> Unit): Result {
inline fun remedys(initiate: RemedyPlan.() -> Unit): Result {
isUsingRemedyPlan = true
if (isNoSuch) RemedyPlan().apply(initiate).build()
return this
@@ -378,7 +383,7 @@ class MethodFinder(
* @param initiate 回调错误
* @return [Result] 可继续向下监听
*/
fun onNoSuchMethod(initiate: (Throwable) -> Unit): Result {
inline fun onNoSuchMethod(initiate: (Throwable) -> Unit): Result {
if (isNoSuch) initiate(e ?: Throwable("Initialization Error"))
return this
}

View File

@@ -115,12 +115,13 @@ abstract class BaseFinder(
}
}
/** 是否使用了重查找功能 */
@PublishedApi
internal var isUsingRemedyPlan = false
/** 是否开启忽略错误警告功能 */
internal var isShutErrorPrinting = false
/** 是否使用了重查找功能 */
internal var isUsingRemedyPlan = false
/** 当前找到的 [Member] */
internal var memberInstance: Member? = null

View File

@@ -158,6 +158,7 @@ class ModifierRules {
* @param member 实例
* @return [Boolean] 是否符合条件
*/
@PublishedApi
internal fun contains(member: Member): Boolean {
var conditions = true
if (isPublic) conditions = Modifier.isPublic(member.modifiers)

View File

@@ -103,49 +103,49 @@ fun String.hasClass(loader: ClassLoader?) = try {
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
fun Class<*>.hasField(initiate: FieldFinder.() -> Unit) = field(initiate).ignoredError().isNoSuch.not()
inline fun Class<*>.hasField(initiate: FieldFinder.() -> Unit) = field(initiate).ignoredError().isNoSuch.not()
/**
* 查找方法是否存在
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
fun Class<*>.hasMethod(initiate: MethodFinder.() -> Unit) = method(initiate).ignoredError().isNoSuch.not()
inline fun Class<*>.hasMethod(initiate: MethodFinder.() -> Unit) = method(initiate).ignoredError().isNoSuch.not()
/**
* 查找构造方法是否存在
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
fun Class<*>.hasConstructor(initiate: ConstructorFinder.() -> Unit) = constructor(initiate).ignoredError().isNoSuch.not()
inline fun Class<*>.hasConstructor(initiate: ConstructorFinder.() -> Unit) = constructor(initiate).ignoredError().isNoSuch.not()
/**
* 查询 [Member] 中匹配的描述符
* @param initiate 方法体
* @return [Boolean] 是否存在
*/
fun Member.hasModifiers(initiate: ModifierRules.() -> Unit) = ModifierRules().apply(initiate).contains(this)
inline fun Member.hasModifiers(initiate: ModifierRules.() -> Unit) = ModifierRules().apply(initiate).contains(this)
/**
* 查找并得到变量
* @param initiate 查找方法体
* @return [FieldFinder.Result]
*/
fun Class<*>.field(initiate: FieldFinder.() -> Unit) = FieldFinder(classSet = this).apply(initiate).build()
inline fun Class<*>.field(initiate: FieldFinder.() -> Unit) = FieldFinder(classSet = this).apply(initiate).build()
/**
* 查找并得到方法
* @param initiate 查找方法体
* @return [MethodFinder.Result]
*/
fun Class<*>.method(initiate: MethodFinder.() -> Unit) = MethodFinder(classSet = this).apply(initiate).build()
inline fun Class<*>.method(initiate: MethodFinder.() -> Unit) = MethodFinder(classSet = this).apply(initiate).build()
/**
* 查找并得到构造类
* @param initiate 查找方法体
* @return [ConstructorFinder.Result]
*/
fun Class<*>.constructor(initiate: ConstructorFinder.() -> Unit) = ConstructorFinder(classSet = this).apply(initiate).build()
inline fun Class<*>.constructor(initiate: ConstructorFinder.() -> Unit) = ConstructorFinder(classSet = this).apply(initiate).build()
/**
* 获得当前实例的类操作对象
@@ -157,39 +157,40 @@ inline fun <reified T : Any> T.current(initiate: CurrentClass.() -> Unit): T {
return this
}
/**
* 通过构造方法创建新实例 - 指定类型 [T]
* @param param 方法参数
* @param initiate 查找方法体
* @return [T] or null
*/
fun <T> Class<*>.buildOf(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = {}) = constructor(initiate).get().newInstance<T>(*param)
/**
* 通过构造方法创建新实例 - 任意类型 [Any]
* @param param 方法参数
* @param initiate 查找方法体
* @return [Any] or null
*/
fun Class<*>.buildOfAny(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = {}) = buildOf<Any?>(*param, initiate)
inline fun Class<*>.buildOfAny(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = {}) = constructor(initiate).get().call(*param)
/**
* 通过构造方法创建新实例 - 指定类型 [T]
* @param param 方法参数
* @param initiate 查找方法体
* @return [T] or null
*/
inline fun <T> Class<*>.buildOf(vararg param: Any?, initiate: ConstructorFinder.() -> Unit = {}) =
constructor(initiate).get().newInstance<T>(*param)
/**
* 遍历当前类中的所有方法
* @param callback 回调 - ([Int] 下标,[Method] 实例)
*/
fun Class<*>.allMethods(callback: (index: Int, method: Method) -> Unit) =
inline fun Class<*>.allMethods(callback: (index: Int, method: Method) -> Unit) =
declaredMethods.forEachIndexed { p, it -> callback(p, it.apply { isAccessible = true }) }
/**
* 遍历当前类中的所有构造方法
* @param callback 回调 - ([Int] 下标,[Constructor] 实例)
*/
fun Class<*>.allConstructors(callback: (index: Int, constructor: Constructor<*>) -> Unit) =
inline fun Class<*>.allConstructors(callback: (index: Int, constructor: Constructor<*>) -> Unit) =
declaredConstructors.forEachIndexed { p, it -> callback(p, it.apply { isAccessible = true }) }
/**
* 遍历当前类中的所有变量
* @param callback 回调 - ([Int] 下标,[Field] 实例)
*/
fun Class<*>.allFields(callback: (index: Int, field: Field) -> Unit) =
inline fun Class<*>.allFields(callback: (index: Int, field: Field) -> Unit) =
declaredFields.forEachIndexed { p, it -> callback(p, it.apply { isAccessible = true }) }

View File

@@ -49,7 +49,7 @@ import java.io.FileReader
* 在 [IYukiHookXposedInit] 中装载 [YukiHookAPI.Configs]
* @param initiate Hook 方法体
*/
fun IYukiHookXposedInit.configs(initiate: YukiHookAPI.Configs.() -> Unit) = YukiHookAPI.configs(initiate)
inline fun IYukiHookXposedInit.configs(initiate: YukiHookAPI.Configs.() -> Unit) = YukiHookAPI.configs(initiate)
/**
* 在 [IYukiHookXposedInit] 中装载 [YukiHookAPI]
@@ -65,7 +65,7 @@ fun IYukiHookXposedInit.encase(initiate: PackageParam.() -> Unit) = YukiHookAPI.
fun IYukiHookXposedInit.encase(vararg hooker: YukiBaseHooker) = YukiHookAPI.encase(hooker = hooker)
@Deprecated("请将接口转移到 IYukiHookXposedInit")
fun YukiHookXposedInitProxy.configs(initiate: YukiHookAPI.Configs.() -> Unit) = YukiHookAPI.configs(initiate)
inline fun YukiHookXposedInitProxy.configs(initiate: YukiHookAPI.Configs.() -> Unit) = YukiHookAPI.configs(initiate)
@Deprecated("请将接口转移到 IYukiHookXposedInit")
fun YukiHookXposedInitProxy.encase(initiate: PackageParam.() -> Unit) = YukiHookAPI.encase(initiate)

View File

@@ -116,7 +116,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param anotherParam 另一个 [PackageParam]
*/
internal fun baseAssignInstance(anotherParam: PackageParam) {
thisParam.wrapper = anotherParam.wrapper
this.wrapper = anotherParam.wrapper
}
/**
@@ -124,7 +124,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param name 包名
* @param initiate 方法体
*/
fun loadApp(name: String, initiate: PackageParam.() -> Unit) {
inline fun loadApp(name: String, initiate: PackageParam.() -> Unit) {
if (packageName == name) initiate(this)
}
@@ -142,7 +142,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param name 进程名 - 若要指定主进程可填写 [mainProcessName] - 效果与 [isFirstApplication] 一致
* @param initiate 方法体
*/
fun withProcess(name: String, initiate: PackageParam.() -> Unit) {
inline fun withProcess(name: String, initiate: PackageParam.() -> Unit) {
if (processName == name) initiate(this)
}
@@ -219,7 +219,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param initiate 方法体
* @return [YukiHookCreater.Result]
*/
fun String.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
inline fun String.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
findClass(name = this).hook(isUseAppClassLoader, initiate)
/**
@@ -228,7 +228,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param initiate 方法体
* @return [YukiHookCreater.Result]
*/
fun Class<*>.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
inline fun Class<*>.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
hookClass.hook(isUseAppClassLoader, initiate)
/**
@@ -237,7 +237,7 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param initiate 方法体
* @return [YukiHookCreater.Result]
*/
fun VariousClass.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
inline fun VariousClass.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
hookClass(if (isUseAppClassLoader) appClassLoader else null).hook(isUseAppClassLoader, initiate)
/**
@@ -246,15 +246,16 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* @param initiate 方法体
* @return [YukiHookCreater.Result]
*/
fun HookClass.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
YukiHookCreater(packageParam = thisParam, hookClass = if (isUseAppClassLoader) bind() else this).apply(initiate).hook()
inline fun HookClass.hook(isUseAppClassLoader: Boolean = true, initiate: YukiHookCreater.() -> Unit) =
YukiHookCreater(packageParam = this@PackageParam, hookClass = if (isUseAppClassLoader) bind() else this).apply(initiate).hook()
/**
* [VariousClass] 转换为 [HookClass] 并绑定到 [appClassLoader]
* @param loader 当前 [ClassLoader] - 若留空使用默认 [ClassLoader]
* @return [HookClass]
*/
private fun VariousClass.hookClass(loader: ClassLoader? = null) = try {
@PublishedApi
internal fun VariousClass.hookClass(loader: ClassLoader? = null) = try {
get(loader).hookClass
} catch (e: Throwable) {
HookClass(name = "VariousClass", throwable = Throwable(e.message))
@@ -266,17 +267,12 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
* - ❗请注意未绑定到 [appClassLoader] 的 [Class] 是不安全的 - 调用 [hook] 方法会根据设定自动绑定
* @return [HookClass]
*/
private fun HookClass.bind() = try {
@PublishedApi
internal fun HookClass.bind() = try {
name.clazz.hookClass
} catch (e: Throwable) {
HookClass(name = name, throwable = throwable ?: e)
}
/**
* 返回自身实例
* @return [PackageParam]
*/
private val thisParam get() = this
override fun toString() = "PackageParam by $wrapper"
}

View File

@@ -38,19 +38,20 @@ import com.highcapable.yukihookapi.annotation.YukiPrivateApi
inline fun <R> runBlocking(block: () -> R): RunBlockResult {
val start = System.currentTimeMillis()
block()
return RunBlockResult(after = System.currentTimeMillis() - start)
return RunBlockResult(afterMs = System.currentTimeMillis() - start)
}
/**
* 构造耗时计算结果类
* @param after 耗时
* @param afterMs 耗时
*/
@YukiPrivateApi
class RunBlockResult(private val after: Long) {
class RunBlockResult(@PublishedApi internal val afterMs: Long) {
/**
* 获取耗时计算结果
* @param initiate 回调结果 - ([Long] 耗时)
*/
fun result(initiate: (Long) -> Unit) = initiate(after)
@YukiPrivateApi
inline fun result(initiate: (Long) -> Unit) = initiate(afterMs)
}

View File

@@ -25,7 +25,10 @@
*
* This file is Created by fankes on 2022/2/8.
*/
@file:Suppress("SetWorldReadable", "CommitPrefEdits", "DEPRECATION", "WorldReadableFiles", "unused", "UNCHECKED_CAST")
@file:Suppress(
"SetWorldReadable", "CommitPrefEdits", "DEPRECATION", "WorldReadableFiles",
"unused", "UNCHECKED_CAST", "MemberVisibilityCanBePrivate"
)
package com.highcapable.yukihookapi.hook.xposed.prefs
@@ -489,15 +492,7 @@ class YukiHookModulePrefs(private val context: Context? = null) {
* @param value 默认值 - 未指定默认为 [prefs] 中的 [PrefsData.value]
* @return [T] 只能是 [String]、[Int]、[Float]、[Long]、[Boolean]
*/
inline fun <reified T> get(prefs: PrefsData<T>, value: T = prefs.value): T = when (prefs.value) {
is String -> getString(prefs.key, value as String) as T
is Set<*> -> getStringSet(prefs.key, value as? Set<String> ?: error("Key-Value type ${T::class.java.name} is not allowed")) as T
is Int -> getInt(prefs.key, value as Int) as T
is Float -> getFloat(prefs.key, value as Float) as T
is Long -> getLong(prefs.key, value as Long) as T
is Boolean -> getBoolean(prefs.key, value as Boolean) as T
else -> error("Key-Value type ${T::class.java.name} is not allowed")
}
inline fun <reified T> get(prefs: PrefsData<T>, value: T = prefs.value): T = getPrefsData(prefs.key, value) as T
/**
* 智能存储指定类型的键值
@@ -508,14 +503,47 @@ class YukiHookModulePrefs(private val context: Context? = null) {
* @param prefs 键值实例
* @param value 要存储的值 - 只能是 [String]、[Int]、[Float]、[Long]、[Boolean]
*/
inline fun <reified T> put(prefs: PrefsData<T>, value: T) = when (prefs.value) {
is String -> putString(prefs.key, value as String)
is Set<*> -> putStringSet(prefs.key, value as? Set<String> ?: error("Key-Value type ${T::class.java.name} is not allowed"))
is Int -> putInt(prefs.key, value as Int)
is Float -> putFloat(prefs.key, value as Float)
is Long -> putLong(prefs.key, value as Long)
is Boolean -> putBoolean(prefs.key, value as Boolean)
else -> error("Key-Value type ${T::class.java.name} is not allowed")
inline fun <reified T> put(prefs: PrefsData<T>, value: T) = putPrefsData(prefs.key, value)
/**
* 智能获取指定类型的键值
*
* 封装方法以调用内联方法
* @param key 键值
* @param value 默认值
* @return [Any]
*/
@PublishedApi
internal fun getPrefsData(key: String, value: Any?): Any = when (value) {
is String -> getString(key, value)
is Set<*> -> getStringSet(key, value as? Set<String> ?: error("Key-Value type ${value.javaClass.name} is not allowed"))
is Int -> getInt(key, value)
is Float -> getFloat(key, value)
is Long -> getLong(key, value)
is Boolean -> getBoolean(key, value)
else -> error("Key-Value type ${value?.javaClass?.name} is not allowed")
}
/**
* 智能存储指定类型的键值
*
* 封装方法以调用内联方法
*
* - 在模块 [Context] 环境中使用
*
* - ❗在 [XSharedPreferences] 环境下只读 - 无法使用
* @param key 键值
* @param value 要存储的值 - 只能是 [String]、[Int]、[Float]、[Long]、[Boolean]
*/
@PublishedApi
internal fun putPrefsData(key: String, value: Any?) = when (value) {
is String -> putString(key, value)
is Set<*> -> putStringSet(key, value as? Set<String> ?: error("Key-Value type ${value.javaClass.name} is not allowed"))
is Int -> putInt(key, value)
is Float -> putFloat(key, value)
is Long -> putLong(key, value)
is Boolean -> putBoolean(key, value)
else -> error("Key-Value type ${value?.javaClass?.name} is not allowed")
}
/**
@@ -541,7 +569,7 @@ class YukiHookModulePrefs(private val context: Context? = null) {
* @param result 回调方法体的结果
* @return [T]
*/
private fun <T> resetCacheSet(result: () -> T): T {
private inline fun <T> resetCacheSet(result: () -> T): T {
isUsingKeyValueCache = YukiHookAPI.Configs.isEnableModulePrefsCache
return result()
}
@@ -552,7 +580,7 @@ class YukiHookModulePrefs(private val context: Context? = null) {
* 非模块环境使用会打印警告信息
* @param initiate 在模块环境执行
*/
private fun moduleEnvironment(initiate: () -> Unit) {
private inline fun moduleEnvironment(initiate: () -> Unit) {
if (isXposedEnvironment.not()) initiate()
else yLoggerW(msg = "You cannot use write prefs function in Xposed Environment")
}