优化
This commit is contained in:
@@ -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,13 +137,22 @@ 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 {
|
||||||
AppLog.put("${item.name}替换出错\n${it.localizedMessage}", it)
|
when (it) {
|
||||||
appCtx.toastOnUi("${item.name}替换出错")
|
is RegexTimeoutException -> {
|
||||||
|
item.isEnabled = false
|
||||||
|
appDb.replaceRuleDao.update(item)
|
||||||
|
return it.msg
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
AppLog.put("${item.name}替换出错\n${it.localizedMessage}", it)
|
||||||
|
appCtx.toastOnUi("${item.name}替换出错")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,62 +46,71 @@ 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() {
|
*/
|
||||||
kotlin.runCatching {
|
private val paramsMap by lazy {
|
||||||
//获取系统信息
|
val map = HashMap<String, String>()
|
||||||
paramsMap["MANUFACTURER"] = Build.MANUFACTURER
|
kotlin.runCatching {
|
||||||
paramsMap["BRAND"] = Build.BRAND
|
//获取系统信息
|
||||||
//获取app版本信息
|
map["MANUFACTURER"] = Build.MANUFACTURER
|
||||||
AppConst.appInfo.let {
|
map["BRAND"] = Build.BRAND
|
||||||
paramsMap["versionName"] = it.versionName
|
//获取app版本信息
|
||||||
paramsMap["versionCode"] = it.versionCode.toString()
|
AppConst.appInfo.let {
|
||||||
}
|
map["versionName"] = it.versionName
|
||||||
}
|
map["versionCode"] = it.versionCode.toString()
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存错误信息到文件中
|
|
||||||
*/
|
|
||||||
private fun saveCrashInfo2File(ex: Throwable) {
|
|
||||||
val sb = StringBuilder()
|
|
||||||
for ((key, value) in paramsMap) {
|
|
||||||
sb.append(key).append("=").append(value).append("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
val writer = StringWriter()
|
|
||||||
val printWriter = PrintWriter(writer)
|
|
||||||
ex.printStackTrace(printWriter)
|
|
||||||
var cause: Throwable? = ex.cause
|
|
||||||
while (cause != null) {
|
|
||||||
cause.printStackTrace(printWriter)
|
|
||||||
cause = cause.cause
|
|
||||||
}
|
|
||||||
printWriter.close()
|
|
||||||
val result = writer.toString()
|
|
||||||
sb.append(result)
|
|
||||||
val timestamp = System.currentTimeMillis()
|
|
||||||
val time = format.format(Date())
|
|
||||||
val fileName = "crash-$time-$timestamp.log"
|
|
||||||
context.externalCacheDir?.let { rootFile ->
|
|
||||||
rootFile.getFile("crash").listFiles()?.forEach {
|
|
||||||
if (it.lastModified() < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) {
|
|
||||||
it.delete()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileUtils.createFileIfNotExist(rootFile, "crash", fileName)
|
map
|
||||||
.writeText(sb.toString())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化时间
|
||||||
|
*/
|
||||||
|
@SuppressLint("SimpleDateFormat")
|
||||||
|
private val format = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存错误信息到文件中
|
||||||
|
*/
|
||||||
|
fun saveCrashInfo2File(ex: Throwable) {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for ((key, value) in paramsMap) {
|
||||||
|
sb.append(key).append("=").append(value).append("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
val writer = StringWriter()
|
||||||
|
val printWriter = PrintWriter(writer)
|
||||||
|
ex.printStackTrace(printWriter)
|
||||||
|
var cause: Throwable? = ex.cause
|
||||||
|
while (cause != null) {
|
||||||
|
cause.printStackTrace(printWriter)
|
||||||
|
cause = cause.cause
|
||||||
|
}
|
||||||
|
printWriter.close()
|
||||||
|
val result = writer.toString()
|
||||||
|
sb.append(result)
|
||||||
|
val timestamp = System.currentTimeMillis()
|
||||||
|
val time = format.format(Date())
|
||||||
|
val fileName = "crash-$time-$timestamp.log"
|
||||||
|
appCtx.externalCacheDir?.let { rootFile ->
|
||||||
|
rootFile.getFile("crash").listFiles()?.forEach {
|
||||||
|
if (it.lastModified() < System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) {
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileUtils.createFileIfNotExist(rootFile, "crash", fileName)
|
||||||
|
.writeText(sb.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
Reference in New Issue
Block a user