fix: 配置无响应问题

This commit is contained in:
HapeLee
2026-06-08 13:51:30 +08:00
parent 5db49a101c
commit 8d12e03113
@@ -19,6 +19,7 @@ import io.legado.app.utils.putPrefStringSync
import io.legado.app.help.config.DsSync
import androidx.datastore.preferences.core.*
import io.legado.app.data.repository.dataStore
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import splitties.init.appCtx
import java.io.IOException
import kotlin.properties.ReadWriteProperty
@@ -35,11 +37,13 @@ import kotlin.reflect.KProperty
interface PrefDelegate<T> : ReadWriteProperty<Any?, T> {
val state: State<T>
val ready: CompletableDeferred<Unit>
fun dispose()
}
class PrefStateDelegate<T>(private val delegate: PrefDelegate<T>) : ReadWriteProperty<Any?, T> by delegate {
val state: State<T> get() = delegate.state
val ready: CompletableDeferred<Unit> get() = delegate.ready
}
fun <T> prefDelegate(
@@ -54,14 +58,19 @@ fun <T> prefDelegate(
override val state: State<T> get() = _value
private val scope = CoroutineScope(Dispatchers.IO)
private var dsObserverJob: Job? = null
override val ready = CompletableDeferred<Unit>()
init {
// 从 DataStore 读取初始值(DS 为唯一读取源)
// 在 IO 线程读取,切换到 Main 线程更新 MutableState,确保 snapshotFlow 能检测到变化
scope.launch {
val dsValue = readFromDs()
if (dsValue != null) {
_value.value = dsValue
withContext(Dispatchers.Main) {
_value.value = dsValue
}
}
ready.complete(Unit)
}
// 观察 DataStore 变化,用于跨实例同步
dsObserverJob = scope.launch {
@@ -91,7 +100,9 @@ fun <T> prefDelegate(
.distinctUntilChanged()
.collect { dsValue ->
if (dsValue != null && _value.value != dsValue) {
_value.value = dsValue
withContext(Dispatchers.Main) {
_value.value = dsValue
}
onValueChange?.invoke(dsValue)
}
}
@@ -126,7 +137,6 @@ fun <T> prefDelegate(
is Float -> appCtx.putPrefFloat(key, value)
}
// 同步写入 DataStore,确保持久化后再返回
// 异常不阻断流程:SP 已写入,readFromDs() 会回退到 SP 读取
runCatching {
runBlocking(Dispatchers.IO) {
when (value) {