mirror of
https://github.com/gedoor/legado.git
synced 2024-07-04 23:36:56 +08:00
优化
This commit is contained in:
parent
5324dfcec3
commit
d1064c5b4c
|
@ -144,6 +144,7 @@ object PreferKey {
|
|||
const val volumeKeyPage = "volumeKeyPage"
|
||||
const val volumeKeyPageOnPlay = "volumeKeyPageOnPlay"
|
||||
const val mouseWheelPage = "mouseWheelPage"
|
||||
const val recordHeapDump = "recordHeapDump"
|
||||
|
||||
const val cPrimary = "colorPrimary"
|
||||
const val cAccent = "colorAccent"
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
|||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Debug
|
||||
import android.os.Looper
|
||||
import android.webkit.WebSettings
|
||||
import io.legado.app.constant.AppConst
|
||||
|
@ -12,13 +13,24 @@ import io.legado.app.exception.NoStackTraceException
|
|||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.config.LocalConfig
|
||||
import io.legado.app.model.ReadAloud
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.FileDoc
|
||||
import io.legado.app.utils.FileUtils
|
||||
import io.legado.app.utils.createFileIfNotExist
|
||||
import io.legado.app.utils.createFolderReplace
|
||||
import io.legado.app.utils.externalCache
|
||||
import io.legado.app.utils.getFile
|
||||
import io.legado.app.utils.longToastOnUiLegacy
|
||||
import io.legado.app.utils.stackTraceStr
|
||||
import io.legado.app.utils.writeText
|
||||
import splitties.init.appCtx
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
/**
|
||||
* 异常管理类
|
||||
|
@ -69,6 +81,9 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
|
|||
LocalConfig.appCrash = true
|
||||
//保存日志文件
|
||||
saveCrashInfo2File(ex)
|
||||
if (ex is OutOfMemoryError && AppConfig.recordHeapDump) {
|
||||
doHeapDump()
|
||||
}
|
||||
context.longToastOnUiLegacy(ex.stackTraceStr)
|
||||
Thread.sleep(3000)
|
||||
}
|
||||
|
@ -148,6 +163,19 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进行堆转储
|
||||
*/
|
||||
fun doHeapDump() {
|
||||
val heapDir = appCtx
|
||||
.externalCache
|
||||
.getFile("heapDump")
|
||||
heapDir.createFolderReplace()
|
||||
val heapFile = heapDir.getFile("heap-dump-${System.currentTimeMillis()}.hprof")
|
||||
val heapDumpName = heapFile.absolutePath
|
||||
Debug.dumpHprofData(heapDumpName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -449,6 +449,8 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
|||
|
||||
val recordLog get() = appCtx.getPrefBoolean(PreferKey.recordLog)
|
||||
|
||||
val recordHeapDump get() = appCtx.getPrefBoolean(PreferKey.recordHeapDump, false)
|
||||
|
||||
val loadCoverOnlyWifi get() = appCtx.getPrefBoolean(PreferKey.loadCoverOnlyWifi, false)
|
||||
|
||||
val showAddToShelfAlert get() = appCtx.getPrefBoolean(PreferKey.showAddToShelfAlert, true)
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.legado.app.R
|
|||
import io.legado.app.constant.AppConst.appInfo
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.help.AppUpdate
|
||||
import io.legado.app.help.CrashHandler
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.ui.widget.dialog.TextDialog
|
||||
|
@ -61,6 +62,7 @@ class AboutFragment : PreferenceFragmentCompat() {
|
|||
"gzGzh" -> requireContext().sendToClip(getString(R.string.legado_gzh))
|
||||
"crashLog" -> showDialogFragment<CrashLogsDialog>()
|
||||
"saveLog" -> saveLog()
|
||||
"saveHeapDump" -> saveHeapDump()
|
||||
}
|
||||
return super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
|
@ -137,10 +139,50 @@ class AboutFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
}
|
||||
}
|
||||
val heapFile = FileDoc.fromFile(File(appCtx.externalCacheDir, "heapDump")).list()
|
||||
?.firstOrNull()
|
||||
if (heapFile != null) {
|
||||
doc.find("heapDump")?.delete()
|
||||
val heapDumpDoc = doc.createFolderIfNotExist("heapDump")
|
||||
heapFile.openInputStream().getOrNull()?.use { input ->
|
||||
heapDumpDoc.createFileIfNotExist(heapFile.name).openOutputStream().getOrNull()
|
||||
?.use {
|
||||
input.copyTo(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
toastOnUi("已保存至备份目录")
|
||||
}.onError {
|
||||
AppLog.put("保存日志出错\n${it.localizedMessage}", it, true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveHeapDump() {
|
||||
Coroutine.async {
|
||||
val backupPath = AppConfig.backupPath ?: let {
|
||||
toastOnUi("未设置备份目录")
|
||||
return@async
|
||||
}
|
||||
toastOnUi("开始保存堆转储")
|
||||
CrashHandler.doHeapDump()
|
||||
val heapFile = FileDoc.fromFile(File(appCtx.externalCacheDir, "heapDump")).list()
|
||||
?.firstOrNull() ?: let {
|
||||
toastOnUi("未找到堆转储文件")
|
||||
return@async
|
||||
}
|
||||
val doc = FileDoc.fromUri(Uri.parse(backupPath), true)
|
||||
doc.find("heapDump")?.delete()
|
||||
val heapDumpDoc = doc.createFolderIfNotExist("heapDump")
|
||||
heapFile.openInputStream().getOrNull()?.use { input ->
|
||||
heapDumpDoc.createFileIfNotExist(heapFile.name).openOutputStream().getOrNull()
|
||||
?.use {
|
||||
input.copyTo(it)
|
||||
}
|
||||
}
|
||||
toastOnUi("已保存至备份目录")
|
||||
}.onError {
|
||||
AppLog.put("保存堆转储失败\n${it.localizedMessage}", it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,19 @@ package io.legado.app.ui.login
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.net.http.SslError
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.webkit.*
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.SslErrorHandler
|
||||
import android.webkit.WebChromeClient
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseFragment
|
||||
|
@ -16,8 +23,10 @@ import io.legado.app.data.entities.BaseSource
|
|||
import io.legado.app.databinding.FragmentWebViewLoginBinding
|
||||
import io.legado.app.help.http.CookieStore
|
||||
import io.legado.app.lib.theme.accentColor
|
||||
import io.legado.app.utils.gone
|
||||
import io.legado.app.utils.NetworkUtils
|
||||
import io.legado.app.utils.gone
|
||||
import io.legado.app.utils.longSnackbar
|
||||
import io.legado.app.utils.openUrl
|
||||
import io.legado.app.utils.snackbar
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
|
||||
|
@ -89,6 +98,33 @@ class WebViewLoginFragment : BaseFragment(R.layout.fragment_web_view_login) {
|
|||
super.onPageFinished(view, url)
|
||||
}
|
||||
|
||||
override fun shouldOverrideUrlLoading(
|
||||
view: WebView,
|
||||
request: WebResourceRequest
|
||||
): Boolean {
|
||||
return shouldOverrideUrlLoading(request.url)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION", "KotlinRedundantDiagnosticSuppress")
|
||||
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
|
||||
return shouldOverrideUrlLoading(Uri.parse(url))
|
||||
}
|
||||
|
||||
private fun shouldOverrideUrlLoading(url: Uri): Boolean {
|
||||
when (url.scheme) {
|
||||
"http", "https" -> {
|
||||
return false
|
||||
}
|
||||
|
||||
else -> {
|
||||
binding.root.longSnackbar(R.string.jump_to_another_app, R.string.confirm) {
|
||||
context?.openUrl(url)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("WebViewClientOnReceivedSslError")
|
||||
override fun onReceivedSslError(
|
||||
view: WebView?,
|
||||
|
|
|
@ -1141,4 +1141,7 @@
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1144,4 +1144,7 @@
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1144,4 +1144,7 @@
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1140,4 +1140,7 @@ Còn </string>
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1141,4 +1141,7 @@
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1143,4 +1143,7 @@
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1143,4 +1143,7 @@
|
|||
<string name="clear_webview_data_success">清除成功,3秒后自动重启应用</string>
|
||||
<string name="key_page_on_long_press">按键长按翻页</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -1144,4 +1144,7 @@
|
|||
<string name="clear_webview_data_success">Cleared successfully, automatically restarts the application after 3 seconds</string>
|
||||
<string name="key_page_on_long_press">Press and hold the key to turn the page</string>
|
||||
<string name="save_log">保存日志</string>
|
||||
<string name="save_heap_dump">保存堆转储</string>
|
||||
<string name="record_heap_dump_s">当应用发生OOM崩溃时保存堆转储</string>
|
||||
<string name="record_heap_dump_t">记录堆转储</string>
|
||||
</resources>
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
android:title="@string/save_log"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<io.legado.app.lib.prefs.Preference
|
||||
android:key="saveHeapDump"
|
||||
android:title="@string/save_heap_dump"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<io.legado.app.lib.prefs.Preference
|
||||
android:key="privacyPolicy"
|
||||
android:title="@string/privacy_policy"
|
||||
|
|
|
@ -188,6 +188,13 @@
|
|||
android:title="@string/record_log"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<io.legado.app.lib.prefs.SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="recordHeapDump"
|
||||
android:summary="@string/record_heap_dump_s"
|
||||
android:title="@string/record_heap_dump_t"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
</io.legado.app.lib.prefs.PreferenceCategory>
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
*/
|
||||
package com.script
|
||||
|
||||
import org.mozilla.javascript.Scriptable
|
||||
|
||||
abstract class CompiledScript {
|
||||
|
||||
abstract fun getEngine(): ScriptEngine
|
||||
|
@ -10,6 +12,9 @@ abstract class CompiledScript {
|
|||
@Throws(ScriptException::class)
|
||||
abstract fun eval(context: ScriptContext): Any?
|
||||
|
||||
@Throws(ScriptException::class)
|
||||
abstract fun eval(scope: Scriptable): Any?
|
||||
|
||||
@Throws(ScriptException::class)
|
||||
fun eval(bindings: Bindings?): Any? {
|
||||
var ctxt = getEngine().context
|
||||
|
|
|
@ -69,4 +69,26 @@ internal class RhinoCompiledScript(
|
|||
return result
|
||||
}
|
||||
|
||||
override fun eval(scope: Scriptable): Any? {
|
||||
val cx = Context.enter()
|
||||
val result: Any?
|
||||
try {
|
||||
val ret = script.exec(cx, scope)
|
||||
result = engine.unwrapReturnValue(ret)
|
||||
} catch (re: RhinoException) {
|
||||
val line = if (re.lineNumber() == 0) -1 else re.lineNumber()
|
||||
val msg: String = if (re is JavaScriptException) {
|
||||
re.value.toString()
|
||||
} else {
|
||||
re.toString()
|
||||
}
|
||||
val se = ScriptException(msg, re.sourceName(), line)
|
||||
se.initCause(re)
|
||||
throw se
|
||||
} finally {
|
||||
Context.exit()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user