Load extensions off the main thread (#3788)
Assisted-by: Claude:claude-opus-5
This commit is contained in:
@@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.extension.util.ExtensionInstaller
|
|||||||
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@@ -23,6 +24,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.emptyFlow
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import logcat.LogPriority
|
import logcat.LogPriority
|
||||||
import tachiyomi.core.common.util.lang.withUIContext
|
import tachiyomi.core.common.util.lang.withUIContext
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
@@ -72,9 +74,11 @@ class ExtensionManager(
|
|||||||
val untrustedExtensionsFlow = untrustedExtensionMapFlow.mapExtensions(scope)
|
val untrustedExtensionsFlow = untrustedExtensionMapFlow.mapExtensions(scope)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
initExtensions()
|
initExtensions()
|
||||||
ExtensionInstallReceiver(InstallationListener()).register(context)
|
ExtensionInstallReceiver(InstallationListener()).register(context)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages.isSet()
|
private var subLanguagesEnabledOnFirstRun = preferences.enabledLanguages.isSet()
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import eu.kanade.tachiyomi.source.SourceFactory
|
|||||||
import eu.kanade.tachiyomi.util.lang.Hash
|
import eu.kanade.tachiyomi.util.lang.Hash
|
||||||
import eu.kanade.tachiyomi.util.storage.copyAndSetReadOnlyTo
|
import eu.kanade.tachiyomi.util.storage.copyAndSetReadOnlyTo
|
||||||
import eu.kanade.tachiyomi.util.system.ChildFirstPathClassLoader
|
import eu.kanade.tachiyomi.util.system.ChildFirstPathClassLoader
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
@@ -163,7 +164,7 @@ internal object ExtensionLoader {
|
|||||||
if (extPkgs.isEmpty()) return emptyList()
|
if (extPkgs.isEmpty()) return emptyList()
|
||||||
|
|
||||||
// Load each extension concurrently and wait for completion
|
// Load each extension concurrently and wait for completion
|
||||||
return runBlocking {
|
return runBlocking(Dispatchers.IO) {
|
||||||
val deferred = extPkgs.map {
|
val deferred = extPkgs.map {
|
||||||
async { loadExtension(context, it) }
|
async { loadExtension(context, it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
@@ -45,6 +46,8 @@ class AndroidSourceManager(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
|
extensionManager.isInitialized.first { it }
|
||||||
|
|
||||||
extensionManager.installedExtensionsFlow
|
extensionManager.installedExtensionsFlow
|
||||||
.collectLatest { extensions ->
|
.collectLatest { extensions ->
|
||||||
val mutableMap = ConcurrentHashMap<Long, Source>(
|
val mutableMap = ConcurrentHashMap<Long, Source>(
|
||||||
|
|||||||
Reference in New Issue
Block a user