This commit is contained in:
Horis
2025-10-14 11:30:30 +08:00
parent 25f4fced2b
commit de39ddbd13
4 changed files with 64 additions and 1 deletions
+2
View File
@@ -34,6 +34,7 @@ import io.legado.app.help.AppFreezeMonitor
import io.legado.app.help.AppWebDav import io.legado.app.help.AppWebDav
import io.legado.app.help.CrashHandler import io.legado.app.help.CrashHandler
import io.legado.app.help.DefaultData import io.legado.app.help.DefaultData
import io.legado.app.help.DispatchersMonitor
import io.legado.app.help.LifecycleHelp import io.legado.app.help.LifecycleHelp
import io.legado.app.help.RuleBigDataHelp import io.legado.app.help.RuleBigDataHelp
import io.legado.app.help.book.BookHelp import io.legado.app.help.book.BookHelp
@@ -89,6 +90,7 @@ class App : Application() {
.setLogger(EventLogger()) .setLogger(EventLogger())
DefaultData.upVersion() DefaultData.upVersion()
AppFreezeMonitor.init(this@App) AppFreezeMonitor.init(this@App)
DispatchersMonitor.init()
URL.setURLStreamHandlerFactory(ObsoleteUrlFactory(okHttpClient)) URL.setURLStreamHandlerFactory(ObsoleteUrlFactory(okHttpClient))
launch { installGmsTlsProvider(appCtx) } launch { installGmsTlsProvider(appCtx) }
initRhino() initRhino()
@@ -0,0 +1,59 @@
package io.legado.app.help
import io.legado.app.help.config.AppConfig
import io.legado.app.utils.LogUtils
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Default
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.selects.onTimeout
import kotlinx.coroutines.selects.select
import kotlinx.coroutines.withContext
import java.util.concurrent.Executors
object DispatchersMonitor {
private const val TAG = "DispatchersMonitor"
private val dispatcher by lazy {
Executors.newSingleThreadExecutor {
Thread(it, TAG)
}.asCoroutineDispatcher()
}
private val scope = CoroutineScope(dispatcher)
fun init() {
scope.coroutineContext.cancelChildren()
if (!AppConfig.recordLog) {
return
}
monitor(IO)
monitor(Default)
monitor(Main)
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun monitor(dispatcher: CoroutineDispatcher) {
scope.launch {
while (isActive) select {
launch {
withContext(dispatcher) {
delay(3000)
}
}.onJoin {}
onTimeout(5000) {
LogUtils.d(TAG, "Dispatcher $dispatcher is timed out waiting for for 5000ms.")
}
}
}
}
}
@@ -16,6 +16,7 @@ import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppFreezeMonitor import io.legado.app.help.AppFreezeMonitor
import io.legado.app.help.DispatchersMonitor
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.LocalConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
@@ -189,6 +190,7 @@ class OtherConfigFragment : PreferenceFragment(),
LogUtils.logDeviceInfo() LogUtils.logDeviceInfo()
LiveEventBus.config().enableLogger(AppConfig.recordLog) LiveEventBus.config().enableLogger(AppConfig.recordLog)
AppFreezeMonitor.init(appCtx) AppFreezeMonitor.init(appCtx)
DispatchersMonitor.init()
} }
PreferKey.processText -> sharedPreferences?.let { PreferKey.processText -> sharedPreferences?.let {
@@ -203,7 +203,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
if (!AppConfig.showLastUpdateTime || bookshelfLayout != 0) { if (!AppConfig.showLastUpdateTime || bookshelfLayout != 0) {
return return
} }
upLastUpdateTimeJob = lifecycleScope.launch { upLastUpdateTimeJob = viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.RESUMED) { repeatOnLifecycle(Lifecycle.State.RESUMED) {
while (isActive) { while (isActive) {
booksAdapter.upLastUpdateTime() booksAdapter.upLastUpdateTime()