pull/2431/head
kunfei 2 years ago
parent 99b676aa12
commit 3b52addea3
  1. 1
      app/src/main/java/io/legado/app/ui/book/import/BaseImportBookActivity.kt
  2. 50
      app/src/main/java/io/legado/app/utils/RegexExtensions.kt

@ -25,7 +25,6 @@ abstract class BaseImportBookActivity<VB : ViewBinding, VM : ViewModel> : VMBase
* 设置书籍保存位置 * 设置书籍保存位置
*/ */
protected suspend fun setBookStorage() = suspendCoroutine { block -> protected suspend fun setBookStorage() = suspendCoroutine { block ->
AppConfig.defaultBookTreeUri = ""
localBookTreeSelectListener = { localBookTreeSelectListener = {
block.resume(it) block.resume(it)
} }

@ -1,59 +1,35 @@
package io.legado.app.utils package io.legado.app.utils
import androidx.core.os.postDelayed
import com.script.SimpleBindings import com.script.SimpleBindings
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.exception.RegexTimeoutException import io.legado.app.exception.RegexTimeoutException
import io.legado.app.help.CrashHandler
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
private val handler by lazy { buildMainHandler() }
/** /**
* 带有超时检测的正则替换 * 带有超时检测的正则替换
* 超时重启apk,线程不能强制结束,只能重启apk
*/ */
suspend fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String { fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String {
val charSequence = this val charSequence = this
return suspendCancellableCoroutine { block -> val startTime = System.currentTimeMillis()
val thread = Thread { val isJs = replacement.startsWith("@js:")
try { val replacement1 = if (isJs) replacement.substring(4) else replacement
if (replacement.startsWith("@js:")) {
val js = replacement.substring(4)
val pattern = regex.toPattern() val pattern = regex.toPattern()
val matcher = pattern.matcher(charSequence) val matcher = pattern.matcher(charSequence)
val stringBuffer = StringBuffer() val stringBuffer = StringBuffer()
while (matcher.find()) { while (matcher.find()) {
if (System.currentTimeMillis() - startTime > timeout) {
val timeoutMsg = "替换超时,将禁用替换规则"
throw RegexTimeoutException(timeoutMsg)
}
if (isJs) {
val bindings = SimpleBindings() val bindings = SimpleBindings()
bindings["result"] = matcher.group() bindings["result"] = matcher.group()
val jsResult = AppConst.SCRIPT_ENGINE.eval(js, bindings).toString() val jsResult = AppConst.SCRIPT_ENGINE.eval(replacement1, bindings).toString()
matcher.appendReplacement(stringBuffer, jsResult) matcher.appendReplacement(stringBuffer, jsResult)
}
matcher.appendTail(stringBuffer)
block.resume(stringBuffer.toString())
} else { } else {
val result = regex.replace(charSequence, replacement) matcher.appendReplacement(stringBuffer, replacement1)
block.resume(result)
}
} catch (e: Exception) {
block.resumeWithException(e)
}
}
thread.start()
handler.postDelayed(timeout) {
if (thread.isAlive) {
runCatching {
@Suppress("DEPRECATION")
thread.stop()
}
val timeoutMsg = "替换超时,将禁用替换规则"
val exception = RegexTimeoutException(timeoutMsg)
block.cancel(exception)
CrashHandler.saveCrashInfo2File(exception)
}
} }
} }
matcher.appendTail(stringBuffer)
return stringBuffer.toString()
} }

Loading…
Cancel
Save