Parcourir la source

fix: 自动跳转最近阅读打开崩溃

HapeLee il y a 5 mois
Parent
commit
1a99cdbac3
1 fichiers modifiés avec 18 ajouts et 5 suppressions
  1. 18 5
      app/src/main/java/io/legado/app/ui/config/PrefDelegate.kt

+ 18 - 5
app/src/main/java/io/legado/app/ui/config/PrefDelegate.kt

@@ -3,6 +3,7 @@ package io.legado.app.ui.config
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.State
 import androidx.compose.runtime.State
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.snapshots.Snapshot
 import androidx.datastore.preferences.core.booleanPreferencesKey
 import androidx.datastore.preferences.core.booleanPreferencesKey
 import androidx.datastore.preferences.core.emptyPreferences
 import androidx.datastore.preferences.core.emptyPreferences
 import androidx.datastore.preferences.core.floatPreferencesKey
 import androidx.datastore.preferences.core.floatPreferencesKey
@@ -57,6 +58,9 @@ fun <T> prefDelegate(
     return object : PrefDelegate<T>, DefaultLifecycleObserver {
     return object : PrefDelegate<T>, DefaultLifecycleObserver {
         private var _value: MutableState<T>
         private var _value: MutableState<T>
         override val state: State<T> get() = _value
         override val state: State<T> get() = _value
+
+        @Volatile
+        private var currentValue: T = defaultValue
         private val scope = CoroutineScope(Dispatchers.IO)
         private val scope = CoroutineScope(Dispatchers.IO)
         private var dsObserverJob: Job? = null
         private var dsObserverJob: Job? = null
 
 
@@ -64,6 +68,8 @@ fun <T> prefDelegate(
             // 同步从 DataStore 读取初始值,确保构造完成后即为最新值
             // 同步从 DataStore 读取初始值,确保构造完成后即为最新值
             val initialValue = runBlocking(Dispatchers.IO) { readFromDs() } ?: defaultValue
             val initialValue = runBlocking(Dispatchers.IO) { readFromDs() } ?: defaultValue
             _value = mutableStateOf(initialValue)
             _value = mutableStateOf(initialValue)
+            currentValue = initialValue
+
             // 观察 DataStore 变化,用于跨实例同步
             // 观察 DataStore 变化,用于跨实例同步
             dsObserverJob = scope.launch {
             dsObserverJob = scope.launch {
                 appCtx.dataStore.data
                 appCtx.dataStore.data
@@ -91,8 +97,8 @@ fun <T> prefDelegate(
                     }
                     }
                     .distinctUntilChanged()
                     .distinctUntilChanged()
                     .collect { dsValue ->
                     .collect { dsValue ->
-                        if (dsValue != null && _value.value != dsValue) {
-                            _value.value = dsValue
+                        if (dsValue != null && currentValue != dsValue) {
+                            updateValue(dsValue)
                             onValueChange?.invoke(dsValue)
                             onValueChange?.invoke(dsValue)
                         }
                         }
                     }
                     }
@@ -112,12 +118,12 @@ fun <T> prefDelegate(
         }
         }
 
 
         override fun getValue(thisRef: Any?, property: KProperty<*>): T {
         override fun getValue(thisRef: Any?, property: KProperty<*>): T {
-            return _value.value
+            return currentValue
         }
         }
 
 
         override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
         override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
-            if (_value.value != value) {
-                _value.value = value
+            if (currentValue != value) {
+                updateValue(value)
                 // 同步写入 SP(向后兼容:AppConfig/MainViewModel 等仍直接读 SP)
                 // 同步写入 SP(向后兼容:AppConfig/MainViewModel 等仍直接读 SP)
                 when (value) {
                 when (value) {
                     is String? -> if (sync) appCtx.putPrefStringSync(key, value) else appCtx.putPrefString(key, value)
                     is String? -> if (sync) appCtx.putPrefStringSync(key, value) else appCtx.putPrefString(key, value)
@@ -204,6 +210,13 @@ fun <T> prefDelegate(
             }
             }
             return spValue
             return spValue
         }
         }
+
+        private fun updateValue(value: T) {
+            currentValue = value
+            Snapshot.withMutableSnapshot {
+                _value.value = value
+            }
+        }
     }
     }
 }
 }