优化
This commit is contained in:
@@ -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?,
|
||||
|
||||
Reference in New Issue
Block a user