From 4cc04b20d50f01b7cfdb4f70312fe227c1284000 Mon Sep 17 00:00:00 2001 From: HapeLee <63206378+HapeLee@users.noreply.github.com> Date: Sun, 7 Jun 2026 23:56:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20DataStore=E8=BF=81=E7=A7=BB=E5=90=8E?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=E9=85=8D=E7=BD=AE=E4=B8=A2=E5=A4=B1=E5=AF=BC?= =?UTF-8?q?=E8=87=B4composeEngine=E9=87=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit postMigrationSync()在App启动时校验SP中的主题key,若缺失则从DataStore补回。 解决进入ReadBookScreen触发首次DS访问后,composeEngine等配置被重置的问题。 --- app/src/main/java/io/legado/app/App.kt | 5 +++ .../app/data/repository/SettingsRepository.kt | 43 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index 582ab728b..b64119d81 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -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().postMigrationSync() + } //预下载Cronet so Cronet.preDownload() createNotificationChannels() diff --git a/app/src/main/java/io/legado/app/data/repository/SettingsRepository.kt b/app/src/main/java/io/legado/app/data/repository/SettingsRepository.kt index 3b55c5fee..bde23ab4f 100644 --- a/app/src/main/java/io/legado/app/data/repository/SettingsRepository.kt +++ b/app/src/main/java/io/legado/app/data/repository/SettingsRepository.kt @@ -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() + 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 ->