refactor: optimize core finder code

- fix remedy plan not show any errors problem
- rearrange some code
This commit is contained in:
2023-09-24 01:09:17 +08:00
parent 373899ba5a
commit f1500f0733
6 changed files with 80 additions and 117 deletions

View File

@@ -48,7 +48,7 @@ abstract class ClassBaseFinder internal constructor(internal open val loaderSet:
internal var classInstances = HashSet<Class<*>>()
/** 是否开启忽略错误警告功能 */
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

View File

@@ -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<Member>()
/** 需要输出的日志内容 */
private var loggingContent: Pair<String, Throwable?>? = 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<Throwable> = 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) }
}
}
}

View File

@@ -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
}
}

View File

@@ -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<Throwable>()
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
}

View File

@@ -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<Throwable>()
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
}

View File

@@ -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<Throwable>()
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
}