pull/2431/head
			
			
		
		
							parent
							
								
									99b676aa12
								
							
						
					
					
						commit
						3b52addea3
					
				| @ -1,59 +1,35 @@ | ||||
| package io.legado.app.utils | ||||
| 
 | ||||
| import androidx.core.os.postDelayed | ||||
| import com.script.SimpleBindings | ||||
| import io.legado.app.constant.AppConst | ||||
| 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 | ||||
|     return suspendCancellableCoroutine { block -> | ||||
|         val thread = Thread { | ||||
|             try { | ||||
|                 if (replacement.startsWith("@js:")) { | ||||
|                     val js = replacement.substring(4) | ||||
|                     val pattern = regex.toPattern() | ||||
|                     val matcher = pattern.matcher(charSequence) | ||||
|                     val stringBuffer = StringBuffer() | ||||
|                     while (matcher.find()) { | ||||
|                         val bindings = SimpleBindings() | ||||
|                         bindings["result"] = matcher.group() | ||||
|                         val jsResult = AppConst.SCRIPT_ENGINE.eval(js, bindings).toString() | ||||
|                         matcher.appendReplacement(stringBuffer, jsResult) | ||||
|                     } | ||||
|                     matcher.appendTail(stringBuffer) | ||||
|                     block.resume(stringBuffer.toString()) | ||||
|                 } else { | ||||
|                     val result = regex.replace(charSequence, replacement) | ||||
|                     block.resume(result) | ||||
|                 } | ||||
|             } catch (e: Exception) { | ||||
|                 block.resumeWithException(e) | ||||
|             } | ||||
|     val startTime = System.currentTimeMillis() | ||||
|     val isJs = replacement.startsWith("@js:") | ||||
|     val replacement1 = if (isJs) replacement.substring(4) else replacement | ||||
|     val pattern = regex.toPattern() | ||||
|     val matcher = pattern.matcher(charSequence) | ||||
|     val stringBuffer = StringBuffer() | ||||
|     while (matcher.find()) { | ||||
|         if (System.currentTimeMillis() - startTime > timeout) { | ||||
|             val timeoutMsg = "替换超时,将禁用替换规则" | ||||
|             throw RegexTimeoutException(timeoutMsg) | ||||
|         } | ||||
|         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) | ||||
|             } | ||||
|         if (isJs) { | ||||
|             val bindings = SimpleBindings() | ||||
|             bindings["result"] = matcher.group() | ||||
|             val jsResult = AppConst.SCRIPT_ENGINE.eval(replacement1, bindings).toString() | ||||
|             matcher.appendReplacement(stringBuffer, jsResult) | ||||
|         } else { | ||||
|             matcher.appendReplacement(stringBuffer, replacement1) | ||||
|         } | ||||
|     } | ||||
|     matcher.appendTail(stringBuffer) | ||||
|     return stringBuffer.toString() | ||||
| } | ||||
| 
 | ||||
|  | ||||
					Loading…
					
					
				
		Reference in new issue