fix: DataStore迁移后主题配置丢失导致composeEngine重置

postMigrationSync()在App启动时校验SP中的主题key,若缺失则从DataStore补回。
解决进入ReadBookScreen触发首次DS访问后,composeEngine等配置被重置的问题。
This commit is contained in:
HapeLee
2026-06-08 00:21:46 +08:00
parent 5897304274
commit 4cc04b20d5
2 changed files with 48 additions and 0 deletions
+5
View File
@@ -44,6 +44,7 @@ import io.legado.app.help.DispatchersMonitor
import io.legado.app.help.LifecycleHelp
import io.legado.app.help.RuleBigDataHelp
import io.legado.app.help.book.BookHelp
import io.legado.app.data.repository.SettingsRepository
import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ThemeConfigStore
import io.legado.app.help.config.ThemeConfigStore.applyDayNightInit
@@ -136,6 +137,10 @@ class App : Application(), ImageLoaderFactory {
LogUtils.init(this@App)
LogUtils.d("App", "onCreate")
LogUtils.logDeviceInfo()
// 确保 DataStore 迁移后 SP 中的主题配置值未丢失
kotlin.runCatching {
get<SettingsRepository>().postMigrationSync()
}
//预下载Cronet so
Cronet.preDownload()
createNotificationChannels()
@@ -1,10 +1,13 @@
package io.legado.app.data.repository
import android.content.Context
import androidx.core.content.edit
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.SharedPreferencesMigration
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import io.legado.app.constant.PreferKey
import io.legado.app.utils.defaultSharedPreferences
import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.putPrefFloat
import io.legado.app.utils.putPrefInt
@@ -14,6 +17,7 @@ import io.legado.app.utils.putPrefStringSet
import io.legado.app.utils.removePref
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import java.io.IOException
@@ -149,6 +153,45 @@ class SettingsRepository(private val context: Context) {
}
}
/**
* DataStore 迁移后同步校验:确保 SP 中的主题配置值未被迁移过程丢失。
*
* SharedPreferencesMigration 在首次访问 DataStore 时运行,将 SP 值复制到 DataStore。
* 在某些场景下(进程被杀、ROM 行为等),迁移可能导致 SP 中的值丢失。
* 此方法从 DataStore 读取关键主题配置,如果 SP 中缺失则补写回去。
*/
suspend fun postMigrationSync() {
val prefs = dataStore.data.first()
val sp = context.defaultSharedPreferences
val themeKeys = listOf(
PreferKey.composeEngine,
PreferKey.appTheme,
PreferKey.themeMode,
PreferKey.paletteStyle,
PreferKey.materialVersion,
PreferKey.customContrast,
PreferKey.customMode,
)
var needsWrite = false
val editor = mutableMapOf<String, String>()
for (key in themeKeys) {
if (!sp.contains(key)) {
val dsValue = prefs[stringPreferencesKey(key)]
if (dsValue != null) {
editor[key] = dsValue
needsWrite = true
}
}
}
if (needsWrite) {
sp.edit {
editor.forEach { (key, value) ->
putString(key, value)
}
}
}
}
// 移除配置
suspend fun remove(key: String) {
dataStore.edit { preferences ->