From f1500f073342577190c3ab87c64b54c4e6fc4a99 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Sun, 24 Sep 2023 01:09:17 +0800 Subject: [PATCH] refactor: optimize core finder code - fix remedy plan not show any errors problem - rearrange some code --- .../finder/base/ClassBaseFinder.kt | 16 +++--- .../finder/base/MemberBaseFinder.kt | 51 +++++++------------ .../finder/classes/DexClassFinder.kt | 10 ++-- .../finder/members/ConstructorFinder.kt | 40 ++++++--------- .../finder/members/FieldFinder.kt | 40 ++++++--------- .../finder/members/MethodFinder.kt | 40 ++++++--------- 6 files changed, 80 insertions(+), 117 deletions(-) diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/ClassBaseFinder.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/ClassBaseFinder.kt index 28d7abf..8a408c6 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/ClassBaseFinder.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/ClassBaseFinder.kt @@ -48,7 +48,7 @@ abstract class ClassBaseFinder internal constructor(internal open val loaderSet: internal var classInstances = HashSet>() /** 是否开启忽略错误警告功能 */ - internal var isShutErrorPrinting = false + internal var isIgnoreErrorLogs = false /** * 将目标类型转换为可识别的兼容类型 @@ -60,21 +60,21 @@ abstract class ClassBaseFinder internal constructor(internal open val loaderSet: /** * 在开启 [YukiReflection.Configs.isDebug] 的情况下输出调试信息 - * @param msg 调试日志内容 + * @param msg 消息内容 */ - internal fun onDebuggingMsg(msg: String) { + internal fun debugMsg(msg: String) { if (YukiReflection.Configs.isDebug) YukiLog.debug(msg) } /** * 发生错误时输出日志 - * @param throwable 错误 + * @param e 异常堆栈 - 默认空 */ - internal fun onFailureMsg(throwable: Throwable? = null) { - if (isShutErrorPrinting) return + internal fun errorMsg(e: Throwable? = null) { + if (isIgnoreErrorLogs) return /** 判断是否为 [LOADERSET_IS_NULL] */ - if (throwable?.message == LOADERSET_IS_NULL) return - YukiLog.error(msg = "NoClassDefFound happend in [$loaderSet]", e = throwable) + if (e?.message == LOADERSET_IS_NULL) return + YukiLog.error(msg = "NoClassDefFound happend in [$loaderSet]", e = e) } @YukiPrivateApi diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/MemberBaseFinder.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/MemberBaseFinder.kt index 0abb7ce..6dc7a72 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/MemberBaseFinder.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/base/MemberBaseFinder.kt @@ -59,14 +59,11 @@ abstract class MemberBaseFinder internal constructor( internal var isUsingRemedyPlan = false /** 是否开启忽略错误警告功能 */ - internal var isShutErrorPrinting = false + internal var isIgnoreErrorLogs = false /** 当前找到的 [Member] 数组 */ internal var memberInstances = HashSet() - /** 需要输出的日志内容 */ - private var loggingContent: Pair? = null - /** * 将 [HashSet]<[Member]> 转换为 [HashSet]<[Field]> * @return [HashSet]<[Field]> @@ -95,38 +92,28 @@ abstract class MemberBaseFinder internal constructor( internal fun Any?.compat() = compat(tag, classSet?.classLoader) /** - * 发生错误时输出日志 - * @param msg 消息日志 - * @param throwable 错误 - * @param isAlwaysPrint 忽略条件每次都打印错误 + * 在开启 [YukiReflection.Configs.isDebug] 的情况下输出调试信息 + * @param msg 消息内容 */ - internal fun onFailureMsg(msg: String = "", throwable: Throwable? = null, isAlwaysPrint: Boolean = false) { - /** 创建日志 */ - fun build() { - if (isUsingRemedyPlan.not() && isShutErrorPrinting.not()) loggingContent = Pair(msg, throwable) - } - /** 判断是否为 [CLASSSET_IS_NULL] */ - if (throwable?.message == CLASSSET_IS_NULL) return - /** 判断始终输出日志或等待结果后输出日志 */ - if (isAlwaysPrint) build().run { printLogIfExist() } - else await { build().run { printLogIfExist() } } - } - - /** 存在日志时输出日志 */ - internal fun printLogIfExist() { - if (loggingContent != null) YukiLog.error( - msg = "NoSuch$tag happend in [$classSet] ${loggingContent?.first}", - e = loggingContent?.second - ) - /** 仅输出一次 - 然后清掉日志 */ - loggingContent = null + internal fun debugMsg(msg: String) { + if (YukiReflection.Configs.isDebug) YukiLog.debug(msg) } /** - * 在开启 [YukiReflection.Configs.isDebug] 的情况下输出调试信息 - * @param msg 调试日志内容 + * 发生错误时输出日志 + * @param msg 消息内容 + * @param e 异常堆栈 - 默认空 + * @param e 异常堆栈数组 - 默认空 + * @param isAlwaysMode 忽略条件每次都输出日志 */ - internal fun onDebuggingMsg(msg: String) { - if (YukiReflection.Configs.isDebug) YukiLog.debug(msg) + internal fun errorMsg(msg: String = "", e: Throwable? = null, es: List = emptyList(), isAlwaysMode: Boolean = false) { + /** 判断是否为 [CLASSSET_IS_NULL] */ + if (e?.message == CLASSSET_IS_NULL) return + await { + if (isIgnoreErrorLogs) return@await + if (isAlwaysMode.not() && isUsingRemedyPlan) return@await + YukiLog.error(msg = "NoSuch$tag happend in [$classSet] $msg".trim(), e = e) + es.forEachIndexed { index, e -> YukiLog.error(msg = "Throwable [${index + 1}]", e = e) } + } } } \ No newline at end of file diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/classes/DexClassFinder.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/classes/DexClassFinder.kt index d139282..2211a15 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/classes/DexClassFinder.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/classes/DexClassFinder.kt @@ -475,7 +475,7 @@ class DexClassFinder @PublishedApi internal constructor( fun startProcess() { runBlocking { setInstance(readFromCache().takeIf { it.isNotEmpty() } ?: result) - }.result { ms -> classInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Class [$it] takes ${ms}ms") } } + }.result { ms -> classInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Class [$it] takes ${ms}ms") } } } Result().also { e -> if (async) e.await { @@ -488,12 +488,12 @@ class DexClassFinder @PublishedApi internal constructor( it.isNotFound = true it.throwable = e it.noClassDefFoundErrorCallback?.invoke() - onFailureMsg(throwable = e) + errorMsg(e = e) } } else startProcess() } - } else Result(isNotFound = true, Throwable(LOADERSET_IS_NULL)).await { onFailureMsg() } - }.getOrElse { e -> Result(isNotFound = true, e).await { onFailureMsg(throwable = e) } } + } else Result(isNotFound = true, Throwable(LOADERSET_IS_NULL)).await { errorMsg() } + }.getOrElse { e -> Result(isNotFound = true, e).await { errorMsg(e = e) } } /** * [Class] 查找结果实现类 @@ -611,7 +611,7 @@ class DexClassFinder @PublishedApi internal constructor( * @return [Result] 可继续向下监听 */ fun ignored(): Result { - isShutErrorPrinting = true + isIgnoreErrorLogs = true return this } } diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/ConstructorFinder.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/ConstructorFinder.kt index 14bc93b..1ebe72d 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/ConstructorFinder.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/ConstructorFinder.kt @@ -248,7 +248,7 @@ class ConstructorFinder @PublishedApi internal constructor(@PublishedApi overrid runBlocking { setInstance(result) }.result { ms -> - memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Constructor [$it] takes ${ms}ms") } + memberInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Constructor [$it] takes ${ms}ms") } } } @@ -257,7 +257,7 @@ class ConstructorFinder @PublishedApi internal constructor(@PublishedApi overrid internalBuild() Result() }.getOrElse { - onFailureMsg(throwable = it) + errorMsg(e = it) Result(isNoSuch = true, it) } @@ -284,41 +284,33 @@ class ConstructorFinder @PublishedApi internal constructor(@PublishedApi overrid * @param initiate 方法体 */ inline fun constructor(initiate: ConstructorConditions) = - Result().apply { remedyPlans.add(Pair(ConstructorFinder(classSet).apply(initiate), this)) } + Result().apply { remedyPlans.add(ConstructorFinder(classSet).apply(initiate) to this) } /** 开始重查找 */ @PublishedApi internal fun build() { if (classSet == null) return - if (remedyPlans.isNotEmpty()) run { + if (remedyPlans.isNotEmpty()) { + val errors = mutableListOf() var isFindSuccess = false - var lastError: Throwable? = null - remedyPlans.forEachIndexed { p, it -> + remedyPlans.forEachIndexed { index, plan -> runCatching { runBlocking { - setInstance(it.first.result) + setInstance(plan.first.result) }.result { ms -> - memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Constructor [$it] takes ${ms}ms") } + memberInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Constructor [$it] takes ${ms}ms") } } isFindSuccess = true - it.second.onFindCallback?.invoke(memberInstances.constructors()) + plan.second.onFindCallback?.invoke(memberInstances.constructors()) remedyPlansCallback?.invoke() memberInstances.takeIf { it.isNotEmpty() } - ?.forEach { onDebuggingMsg(msg = "Constructor [$it] trying ${p + 1} times success by RemedyPlan") } - return@run - }.onFailure { - lastError = it - onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true) - } - } - if (isFindSuccess.not()) { - onFailureMsg( - msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan", - throwable = lastError, - isAlwaysPrint = true - ) - remedyPlans.clear() + ?.forEach { debugMsg(msg = "RemedyPlan successed after ${index + 1} attempts of Constructor [$it]") } + return + }.onFailure { errors.add(it) } } + if (isFindSuccess) return + errorMsg(msg = "RemedyPlan failed after ${remedyPlans.size} attempts", es = errors, isAlwaysMode = true) + remedyPlans.clear() } else YukiLog.warn(msg = "RemedyPlan is empty, forgot it?") } @@ -467,7 +459,7 @@ class ConstructorFinder @PublishedApi internal constructor(@PublishedApi overrid * @return [Result] 可继续向下监听 */ fun ignored(): Result { - isShutErrorPrinting = true + isIgnoreErrorLogs = true return this } diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/FieldFinder.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/FieldFinder.kt index b96205c..ff9e918 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/FieldFinder.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/FieldFinder.kt @@ -206,7 +206,7 @@ class FieldFinder @PublishedApi internal constructor(@PublishedApi override val runBlocking { setInstance(result) }.result { ms -> - memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Field [$it] takes ${ms}ms") } + memberInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Field [$it] takes ${ms}ms") } } } @@ -215,7 +215,7 @@ class FieldFinder @PublishedApi internal constructor(@PublishedApi override val internalBuild() Result() }.getOrElse { - onFailureMsg(throwable = it) + errorMsg(e = it) Result(isNoSuch = true, it) } @@ -242,41 +242,33 @@ class FieldFinder @PublishedApi internal constructor(@PublishedApi override val * @param initiate 方法体 * @return [Result] 结果 */ - inline fun field(initiate: FieldConditions) = Result().apply { remedyPlans.add(Pair(FieldFinder(classSet).apply(initiate), this)) } + inline fun field(initiate: FieldConditions) = Result().apply { remedyPlans.add(FieldFinder(classSet).apply(initiate) to this) } /** 开始重查找 */ @PublishedApi internal fun build() { if (classSet == null) return - if (remedyPlans.isNotEmpty()) run { + if (remedyPlans.isNotEmpty()) { + val errors = mutableListOf() var isFindSuccess = false - var lastError: Throwable? = null - remedyPlans.forEachIndexed { p, it -> + remedyPlans.forEachIndexed { index, plan -> runCatching { runBlocking { - setInstance(it.first.result) + setInstance(plan.first.result) }.result { ms -> - memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Field [$it] takes ${ms}ms") } + memberInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Field [$it] takes ${ms}ms") } } isFindSuccess = true - it.second.onFindCallback?.invoke(memberInstances.fields()) + plan.second.onFindCallback?.invoke(memberInstances.fields()) remedyPlansCallback?.invoke() memberInstances.takeIf { it.isNotEmpty() } - ?.forEach { onDebuggingMsg(msg = "Field [$it] trying ${p + 1} times success by RemedyPlan") } - return@run - }.onFailure { - lastError = it - onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true) - } - } - if (isFindSuccess.not()) { - onFailureMsg( - msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan", - throwable = lastError, - isAlwaysPrint = true - ) - remedyPlans.clear() + ?.forEach { debugMsg(msg = "RemedyPlan successed after ${index + 1} attempts of Field [$it]") } + return + }.onFailure { errors.add(it) } } + if (isFindSuccess) return + errorMsg(msg = "RemedyPlan failed after ${remedyPlans.size} attempts", es = errors, isAlwaysMode = true) + remedyPlans.clear() } else YukiLog.warn(msg = "RemedyPlan is empty, forgot it?") } @@ -437,7 +429,7 @@ class FieldFinder @PublishedApi internal constructor(@PublishedApi override val * @return [Result] 可继续向下监听 */ fun ignored(): Result { - isShutErrorPrinting = true + isIgnoreErrorLogs = true return this } diff --git a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/MethodFinder.kt b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/MethodFinder.kt index 107e970..3b3af5c 100644 --- a/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/MethodFinder.kt +++ b/yukireflection-core/src/main/java/com/highcapable/yukireflection/finder/members/MethodFinder.kt @@ -340,7 +340,7 @@ class MethodFinder @PublishedApi internal constructor(@PublishedApi override val runBlocking { setInstance(result) }.result { ms -> - memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Method [$it] takes ${ms}ms") } + memberInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Method [$it] takes ${ms}ms") } } } @@ -349,7 +349,7 @@ class MethodFinder @PublishedApi internal constructor(@PublishedApi override val internalBuild() Result() }.getOrElse { - onFailureMsg(throwable = it) + errorMsg(e = it) Result(isNoSuch = true, it) } @@ -376,41 +376,33 @@ class MethodFinder @PublishedApi internal constructor(@PublishedApi override val * @param initiate 方法体 * @return [Result] 结果 */ - inline fun method(initiate: MethodConditions) = Result().apply { remedyPlans.add(Pair(MethodFinder(classSet).apply(initiate), this)) } + inline fun method(initiate: MethodConditions) = Result().apply { remedyPlans.add(MethodFinder(classSet).apply(initiate) to this) } /** 开始重查找 */ @PublishedApi internal fun build() { if (classSet == null) return - if (remedyPlans.isNotEmpty()) run { + if (remedyPlans.isNotEmpty()) { + val errors = mutableListOf() var isFindSuccess = false - var lastError: Throwable? = null - remedyPlans.forEachIndexed { p, it -> + remedyPlans.forEachIndexed { index, plan -> runCatching { runBlocking { - setInstance(it.first.result) + setInstance(plan.first.result) }.result { ms -> - memberInstances.takeIf { it.isNotEmpty() }?.forEach { onDebuggingMsg(msg = "Find Method [$it] takes ${ms}ms") } + memberInstances.takeIf { it.isNotEmpty() }?.forEach { debugMsg(msg = "Find Method [$it] takes ${ms}ms") } } isFindSuccess = true - it.second.onFindCallback?.invoke(memberInstances.methods()) + plan.second.onFindCallback?.invoke(memberInstances.methods()) remedyPlansCallback?.invoke() memberInstances.takeIf { it.isNotEmpty() } - ?.forEach { onDebuggingMsg(msg = "Method [$it] trying ${p + 1} times success by RemedyPlan") } - return@run - }.onFailure { - lastError = it - onFailureMsg(msg = "Trying ${p + 1} times by RemedyPlan --> $it", isAlwaysPrint = true) - } - } - if (isFindSuccess.not()) { - onFailureMsg( - msg = "Trying ${remedyPlans.size} times and all failure by RemedyPlan", - throwable = lastError, - isAlwaysPrint = true - ) - remedyPlans.clear() + ?.forEach { debugMsg(msg = "RemedyPlan successed after ${index + 1} attempts of Method [$it]") } + return + }.onFailure { errors.add(it) } } + if (isFindSuccess) return + errorMsg(msg = "RemedyPlan failed after ${remedyPlans.size} attempts", es = errors, isAlwaysMode = true) + remedyPlans.clear() } else YukiLog.warn(msg = "RemedyPlan is empty, forgot it?") } @@ -566,7 +558,7 @@ class MethodFinder @PublishedApi internal constructor(@PublishedApi override val * @return [Result] 可继续向下监听 */ fun ignored(): Result { - isShutErrorPrinting = true + isIgnoreErrorLogs = true return this }