pull/1776/head
kunfei 3 years ago
parent 8cad8fe230
commit 2a2e319b6f
  1. 14
      app/src/main/java/io/legado/app/help/ContentProcessor.kt
  2. 41
      app/src/main/java/io/legado/app/help/CrashHandler.kt
  3. 2
      app/src/main/java/io/legado/app/utils/ContextExtensions.kt
  4. 35
      app/src/main/java/io/legado/app/utils/RegexExtensions.kt

@ -8,6 +8,9 @@ import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ReadBookConfig
import io.legado.app.utils.RegexTimeoutException
import io.legado.app.utils.msg
import io.legado.app.utils.replace
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import splitties.init.appCtx import splitties.init.appCtx
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -134,16 +137,25 @@ class ContentProcessor private constructor(
if (item.pattern.isNotEmpty()) { if (item.pattern.isNotEmpty()) {
kotlin.runCatching { kotlin.runCatching {
mContent = if (item.isRegex) { mContent = if (item.isRegex) {
mContent.replace(item.pattern.toRegex(), item.replacement) mContent.replace(item.pattern.toRegex(), item.replacement, 1000L)
} else { } else {
mContent.replace(item.pattern, item.replacement) mContent.replace(item.pattern, item.replacement)
} }
}.onFailure { }.onFailure {
when (it) {
is RegexTimeoutException -> {
item.isEnabled = false
appDb.replaceRuleDao.update(item)
return it.msg
}
else -> {
AppLog.put("${item.name}替换出错\n${it.localizedMessage}", it) AppLog.put("${item.name}替换出错\n${it.localizedMessage}", it)
appCtx.toastOnUi("${item.name}替换出错") appCtx.toastOnUi("${item.name}替换出错")
} }
} }
} }
}
}
return mContent return mContent
} }

@ -9,6 +9,7 @@ import io.legado.app.utils.FileUtils
import io.legado.app.utils.getFile import io.legado.app.utils.getFile
import io.legado.app.utils.longToastOnUi import io.legado.app.utils.longToastOnUi
import io.legado.app.utils.msg import io.legado.app.utils.msg
import splitties.init.appCtx
import java.io.PrintWriter import java.io.PrintWriter
import java.io.StringWriter import java.io.StringWriter
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -26,17 +27,6 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
*/ */
private var mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler() private var mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
/**
* 存储异常和参数信息
*/
private val paramsMap = HashMap<String, String>()
/**
* 格式化时间
*/
@SuppressLint("SimpleDateFormat")
private val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")
init { init {
//设置该CrashHandler为系统默认的 //设置该CrashHandler为系统默认的
Thread.setDefaultUncaughtExceptionHandler(this) Thread.setDefaultUncaughtExceptionHandler(this)
@ -56,34 +46,41 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
*/ */
private fun handleException(ex: Throwable?) { private fun handleException(ex: Throwable?) {
if (ex == null) return if (ex == null) return
//收集设备参数信息
collectDeviceInfo()
//保存日志文件 //保存日志文件
saveCrashInfo2File(ex) saveCrashInfo2File(ex)
context.longToastOnUi(ex.msg) context.longToastOnUi(ex.msg)
Thread.sleep(3000) Thread.sleep(3000)
} }
companion object {
/** /**
* 收集设备参数信息 * 存储异常和参数信息
*/ */
private fun collectDeviceInfo() { private val paramsMap by lazy {
val map = HashMap<String, String>()
kotlin.runCatching { kotlin.runCatching {
//获取系统信息 //获取系统信息
paramsMap["MANUFACTURER"] = Build.MANUFACTURER map["MANUFACTURER"] = Build.MANUFACTURER
paramsMap["BRAND"] = Build.BRAND map["BRAND"] = Build.BRAND
//获取app版本信息 //获取app版本信息
AppConst.appInfo.let { AppConst.appInfo.let {
paramsMap["versionName"] = it.versionName map["versionName"] = it.versionName
paramsMap["versionCode"] = it.versionCode.toString() map["versionCode"] = it.versionCode.toString()
} }
} }
map
} }
/**
* 格式化时间
*/
@SuppressLint("SimpleDateFormat")
private val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")
/** /**
* 保存错误信息到文件中 * 保存错误信息到文件中
*/ */
private fun saveCrashInfo2File(ex: Throwable) { fun saveCrashInfo2File(ex: Throwable) {
val sb = StringBuilder() val sb = StringBuilder()
for ((key, value) in paramsMap) { for ((key, value) in paramsMap) {
sb.append(key).append("=").append(value).append("\n") sb.append(key).append("=").append(value).append("\n")
@ -103,7 +100,7 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
val timestamp = System.currentTimeMillis() val timestamp = System.currentTimeMillis()
val time = format.format(Date()) val time = format.format(Date())
val fileName = "crash-$time-$timestamp.log" val fileName = "crash-$time-$timestamp.log"
context.externalCacheDir?.let { rootFile -> appCtx.externalCacheDir?.let { rootFile ->
rootFile.getFile("crash").listFiles()?.forEach { rootFile.getFile("crash").listFiles()?.forEach {
if (it.lastModified() < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) { if (it.lastModified() < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) {
it.delete() it.delete()
@ -114,4 +111,6 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
} }
} }
}
} }

@ -33,6 +33,7 @@ import splitties.systemservices.clipboardManager
import splitties.systemservices.connectivityManager import splitties.systemservices.connectivityManager
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import kotlin.system.exitProcess
inline fun <reified A : Activity> Context.startActivity(configIntent: Intent.() -> Unit = {}) { inline fun <reified A : Activity> Context.startActivity(configIntent: Intent.() -> Unit = {}) {
val intent = Intent(this, A::class.java) val intent = Intent(this, A::class.java)
@ -168,6 +169,7 @@ fun Context.restart() {
startActivity(intent) startActivity(intent)
//杀掉以前进程 //杀掉以前进程
Process.killProcess(Process.myPid()) Process.killProcess(Process.myPid())
exitProcess(0)
} }
} }

@ -1,10 +1,37 @@
package io.legado.app.utils package io.legado.app.utils
import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.CrashHandler
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import splitties.init.appCtx
import kotlin.concurrent.thread
import kotlin.coroutines.resume
suspend fun CharSequence.regexReplace(regex: String, replacement: String, timeout: Long): String { suspend fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String {
return suspendCancellableCoroutine { return suspendCancellableCoroutine { block ->
val thread = thread {
try {
val result = regex.replace(this, replacement)
block.resume(result)
} catch (e: Exception) {
block.cancel(e)
}
}
mainHandler.postDelayed({
if (thread.isAlive) {
val timeoutMsg = "替换超时,将在3秒后重启应用\n替换规则$regex\n替换内容:${this}"
val exception = RegexTimeoutException(timeoutMsg)
block.cancel(exception)
appCtx.longToastOnUi(timeoutMsg)
CrashHandler.saveCrashInfo2File(exception)
mainHandler.postDelayed({
if (thread.isAlive) {
appCtx.restart()
}
}, 3000)
}
}, timeout)
} }
} }
class RegexTimeoutException(msg: String) : NoStackTraceException(msg)
Loading…
Cancel
Save