Просмотр исходного кода

feat: SP 监听器替换为 AppConfigStore observe Flow

PR-2: 组B 监听器迁移 —— 删除 AppConfig 的 OnSharedPreferenceChangeListener,
缓存字段退化为 computed get 读快照;WebDavManager/BaseReadAloudService
改用 AppConfigStore.observe* Flow(per-key drop(1) 后 merge)。

- AppConfig: 删除 SharedPreferences.OnSharedPreferenceChangeListener 实现、onSharedPreferenceChanged、syncReadPreferences、syncReadPreferenceFromSharedPreferences、detectClickArea、detectMangaClickArea
- AppConfig: clickAction*/isEInkMode/isTransparent/readBarStyle* 从 var 缓存退化为 val get() 读快照
- App.kt: 删除 defaultSharedPreferences.registerOnSharedPreferenceChangeListener(AppConfig)
- WebDavManager: 删除 SP 监听,改用 5 键 obverseString + drop(1) + merge
- BaseReadAloudService: observeSharedPreferences 替换为 2 键 obverseBoolean + drop(1) + merge
5151561 3 месяцев назад
Родитель
Сommit
1d2081ddff

+ 0 - 1
app/src/main/java/io/legado/app/App.kt

@@ -136,7 +136,6 @@ class App : Application(), ImageLoaderFactory {
         }
         oldConfig = Configuration(resources.configuration)
         registerActivityLifecycleCallbacks(LifecycleHelp)
-        defaultSharedPreferences.registerOnSharedPreferenceChangeListener(AppConfig)
         Coroutine.async {
             AppWebDav.upConfig()
         }

+ 16 - 19
app/src/main/java/io/legado/app/help/WebDavManager.kt

@@ -1,6 +1,5 @@
 package io.legado.app.help
 
-import android.content.SharedPreferences
 import android.net.Uri
 import io.legado.app.constant.PreferKey
 import io.legado.app.data.appDb
@@ -8,6 +7,7 @@ import io.legado.app.data.entities.Book
 import io.legado.app.data.entities.BookProgress
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.config.AppConfig
+import io.legado.app.help.config.AppConfigStore
 import io.legado.app.help.config.LocalConfig
 import io.legado.app.help.storage.Backup
 import io.legado.app.help.storage.BackupRestoreLock
@@ -24,7 +24,6 @@ import io.legado.app.utils.GSON
 import io.legado.app.utils.NetworkUtils
 import io.legado.app.utils.UrlUtil
 import io.legado.app.utils.compress.ZipUtils
-import io.legado.app.utils.defaultSharedPreferences
 import io.legado.app.utils.fromJsonObject
 import io.legado.app.utils.isJson
 import io.legado.app.utils.normalizeFileName
@@ -34,12 +33,13 @@ import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.drop
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
-import splitties.init.appCtx
 import java.io.File
 import kotlin.coroutines.cancellation.CancellationException
 
@@ -67,9 +67,8 @@ sealed class WebDavState {
 }
 
 class WebDavManager(
-    private val prefs: SharedPreferences = appCtx.defaultSharedPreferences,
     private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
-) : SharedPreferences.OnSharedPreferenceChangeListener {
+) {
 
     private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
     private val configFlow = MutableStateFlow(readConfig())
@@ -79,12 +78,22 @@ class WebDavManager(
     private var refreshJob: Job? = null
 
     init {
-        prefs.registerOnSharedPreferenceChangeListener(this)
+        scope.launch {
+            merge(
+                AppConfigStore.observeString(PreferKey.webDavUrl).drop(1),
+                AppConfigStore.observeString(PreferKey.webDavAccount).drop(1),
+                AppConfigStore.observeString(PreferKey.webDavPassword).drop(1),
+                AppConfigStore.observeString(PreferKey.webDavDir).drop(1),
+                AppConfigStore.observeString(PreferKey.webDavDeviceName).drop(1),
+            ).collect {
+                configFlow.value = readConfig()
+                refresh()
+            }
+        }
         refresh()
     }
 
     fun close() {
-        prefs.unregisterOnSharedPreferenceChangeListener(this)
         scope.cancel()
     }
 
@@ -273,18 +282,6 @@ class WebDavManager(
         }
     }
 
-    override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
-        if (key == PreferKey.webDavUrl
-            || key == PreferKey.webDavAccount
-            || key == PreferKey.webDavPassword
-            || key == PreferKey.webDavDir
-            || key == PreferKey.webDavDeviceName
-        ) {
-            configFlow.value = readConfig()
-            refresh()
-        }
-    }
-
     private fun readConfig(): WebDavConfig {
         return WebDavConfig(
             url = BackupConfig.webDavUrl,

+ 15 - 133
app/src/main/java/io/legado/app/help/config/AppConfig.kt

@@ -1,10 +1,8 @@
 package io.legado.app.help.config
 
-import android.content.SharedPreferences
 import io.legado.app.BuildConfig
 import io.legado.app.constant.PreferKey
 import io.legado.app.data.appDb
-import io.legado.app.data.repository.ReadPreferences
 import io.legado.app.data.repository.SettingsRepository
 import io.legado.app.ui.config.backupConfig.BackupConfig
 import io.legado.app.ui.config.bookshelfConfig.BookshelfConfig
@@ -24,14 +22,13 @@ import io.legado.app.utils.putPrefBoolean
 import io.legado.app.utils.putPrefInt
 import io.legado.app.utils.putPrefString
 import io.legado.app.utils.sysConfiguration
-import io.legado.app.utils.toastOnUi
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.runBlocking
 import org.koin.java.KoinJavaComponent.get
 import splitties.init.appCtx
 
 @Suppress("MemberVisibilityCanBePrivate", "ConstPropertyName")
-object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
+object AppConfig {
     private val settingsRepository: SettingsRepository by lazy {
         get(SettingsRepository::class.java)
     }
@@ -39,18 +36,18 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
     val useAntiAlias get() = OtherConfig.antiAlias
     val userAgent: String get() = DownloadCacheConfig.userAgent
 
-    var isEInkMode = appCtx.getPrefString("app_theme", "0") == "4"
-    var isTransparent = appCtx.getPrefString("app_theme", "0") == "13"
+    val isEInkMode get() = appCtx.getPrefString("app_theme", "0") == "4"
+    val isTransparent get() = appCtx.getPrefString("app_theme", "0") == "13"
     val customMode get() = ThemeConfig.customMode
-    var clickActionTL = appCtx.getPrefInt(PreferKey.clickActionTL, 2)
-    var clickActionTC = appCtx.getPrefInt(PreferKey.clickActionTC, 2)
-    var clickActionTR = appCtx.getPrefInt(PreferKey.clickActionTR, 1)
-    var clickActionML = appCtx.getPrefInt(PreferKey.clickActionML, 2)
-    var clickActionMC = appCtx.getPrefInt(PreferKey.clickActionMC, 0)
-    var clickActionMR = appCtx.getPrefInt(PreferKey.clickActionMR, 1)
-    var clickActionBL = appCtx.getPrefInt(PreferKey.clickActionBL, 2)
-    var clickActionBC = appCtx.getPrefInt(PreferKey.clickActionBC, 1)
-    var clickActionBR = appCtx.getPrefInt(PreferKey.clickActionBR, 1)
+    val clickActionTL get() = appCtx.getPrefInt(PreferKey.clickActionTL, 2)
+    val clickActionTC get() = appCtx.getPrefInt(PreferKey.clickActionTC, 2)
+    val clickActionTR get() = appCtx.getPrefInt(PreferKey.clickActionTR, 1)
+    val clickActionML get() = appCtx.getPrefInt(PreferKey.clickActionML, 2)
+    val clickActionMC get() = appCtx.getPrefInt(PreferKey.clickActionMC, 0)
+    val clickActionMR get() = appCtx.getPrefInt(PreferKey.clickActionMR, 1)
+    val clickActionBL get() = appCtx.getPrefInt(PreferKey.clickActionBL, 2)
+    val clickActionBC get() = appCtx.getPrefInt(PreferKey.clickActionBC, 1)
+    val clickActionBR get() = appCtx.getPrefInt(PreferKey.clickActionBR, 1)
 
     //    -1无操作 1下一页 2上一页 0显示菜单
     var mangaClickActionTL
@@ -98,105 +95,6 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
     val adaptSpecialStyle get() = ReadConfig.adaptSpecialStyle
     val useUnderline get() = ReadConfig.useUnderline
 
-    private var readBarStyleFollowPageValue =
-        appCtx.getPrefBoolean(PreferKey.readBarStyleFollowPage, false)
-    private var readBarStyleValue = appCtx.getPrefInt(PreferKey.readBarStyle, 0)
-
-    fun syncReadPreferences(preferences: ReadPreferences) {
-        ReadConfig.optimizeRender = preferences.optimizeRender
-        ReadConfig.adaptSpecialStyle = preferences.adaptSpecialStyle
-        ReadConfig.useUnderline = preferences.useUnderline
-        ReadConfig.chineseConverterType = preferences.chineseConverterType
-        clickActionTL = preferences.clickActionTL
-        clickActionTC = preferences.clickActionTC
-        clickActionTR = preferences.clickActionTR
-        clickActionML = preferences.clickActionML
-        clickActionMC = preferences.clickActionMC
-        clickActionMR = preferences.clickActionMR
-        clickActionBL = preferences.clickActionBL
-        clickActionBC = preferences.clickActionBC
-        clickActionBR = preferences.clickActionBR
-        ReadConfig.screenOrientation = preferences.screenOrientation
-        ReadConfig.noAnimScrollPage = preferences.noAnimScrollPage
-        ReadConfig.tocUiUseReplace = preferences.tocUiUseReplace
-        ReadConfig.tocCountWords = preferences.tocCountWords
-        ReadConfig.autoChangeSource = preferences.autoChangeSource
-        ReadConfig.clickImgWay = preferences.clickImgWay
-        ReadConfig.doubleHorizontalPage = preferences.doubleHorizontalPage
-        ReadConfig.progressBarBehavior = preferences.progressBarBehavior
-        ReadConfig.keyPageOnLongPress = preferences.keyPageOnLongPress
-        ReadConfig.volumeKeyPage = preferences.volumeKeyPage
-        ReadConfig.volumeKeyPageOnPlay = preferences.volumeKeyPageOnPlay
-        ReadConfig.mouseWheelPage = preferences.mouseWheelPage
-        ReadConfig.paddingDisplayCutouts = preferences.paddingDisplayCutouts
-        ReadConfig.pageTouchSlop = preferences.pageTouchSlop
-        ReadConfig.showReadTitleAddition = preferences.showReadTitleAddition
-        ReadConfig.titleBarMode = preferences.titleBarMode
-        ReadBookConfig.readMenuBlurAlpha = preferences.readMenuBlurAlpha
-        ReadBookConfig.readSliderMode = preferences.readSliderMode
-        readBarStyleFollowPageValue = preferences.readBarStyleFollowPage
-        readBarStyleValue = preferences.readBarStyle
-        ReadConfig.defaultSourceChangeAll = preferences.defaultSourceChangeAll
-        ReadConfig.sliderVibrator = preferences.sliderVibrator
-        ReadConfig.selectVibrator = preferences.selectVibrator
-        ReadBookConfig.brightnessVwPos = preferences.brightnessVwPos
-        ReadBookConfig.readBrightness = preferences.readBrightness
-    }
-
-    fun updateReadBarStyleCache(value: Int) {
-        readBarStyleValue = value.coerceIn(0, 2)
-    }
-
-    private fun syncReadPreferenceFromSharedPreferences(key: String?) {
-        when (key) {
-            PreferKey.readBarStyleFollowPage -> readBarStyleFollowPageValue =
-                appCtx.getPrefBoolean(PreferKey.readBarStyleFollowPage, false)
-            PreferKey.readBarStyle -> readBarStyleValue =
-                appCtx.getPrefInt(PreferKey.readBarStyle, 0)
-        }
-    }
-
-
-    override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
-        syncReadPreferenceFromSharedPreferences(key)
-        when (key) {
-
-            PreferKey.clickActionTL -> clickActionTL =
-                appCtx.getPrefInt(PreferKey.clickActionTL, 2)
-
-            PreferKey.clickActionTC -> clickActionTC =
-                appCtx.getPrefInt(PreferKey.clickActionTC, 2)
-
-            PreferKey.clickActionTR -> clickActionTR =
-                appCtx.getPrefInt(PreferKey.clickActionTR, 1)
-
-            PreferKey.clickActionML -> clickActionML =
-                appCtx.getPrefInt(PreferKey.clickActionML, 2)
-
-            PreferKey.clickActionMC -> clickActionMC =
-                appCtx.getPrefInt(PreferKey.clickActionMC, 0)
-
-            PreferKey.clickActionMR -> clickActionMR =
-                appCtx.getPrefInt(PreferKey.clickActionMR, 1)
-
-            PreferKey.clickActionBL -> clickActionBL =
-                appCtx.getPrefInt(PreferKey.clickActionBL, 2)
-
-            PreferKey.clickActionBC -> clickActionBC =
-                appCtx.getPrefInt(PreferKey.clickActionBC, 1)
-
-            PreferKey.clickActionBR -> clickActionBR =
-                appCtx.getPrefInt(PreferKey.clickActionBR, 1)
-
-            PreferKey.readBodyToLh -> ReadBookConfig.readBodyToLh =
-                appCtx.getPrefBoolean(PreferKey.readBodyToLh, true)
-
-            PreferKey.useZhLayout -> ReadBookConfig.useZhLayout =
-                appCtx.getPrefBoolean(PreferKey.useZhLayout)
-
-        }
-    }
-
     var isNightTheme: Boolean
         get() = when (ThemeConfig.themeMode) {
             "1" -> false
@@ -649,17 +547,15 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
         }
 
     var readBarStyleFollowPage: Boolean
-        get() = readBarStyleFollowPageValue
+        get() = appCtx.getPrefBoolean(PreferKey.readBarStyleFollowPage, false)
         set(value) {
-            readBarStyleFollowPageValue = value
             appCtx.putPrefBoolean(PreferKey.readBarStyleFollowPage, value)
         }
 
     var readBarStyle: Int
-        get() = readBarStyleValue
+        get() = appCtx.getPrefInt(PreferKey.readBarStyle, 0)
         set(value) {
-            readBarStyleValue = value.coerceIn(0, 2)
-            appCtx.putPrefInt(PreferKey.readBarStyle, readBarStyleValue)
+            appCtx.putPrefInt(PreferKey.readBarStyle, value.coerceIn(0, 2))
         }
 
     var sourceEditMaxLine: Int
@@ -680,20 +576,6 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
             appCtx.putPrefBoolean(PreferKey.brightnessVwPos, value)
         }
 
-    fun detectClickArea() {
-        if (clickActionTL * clickActionTC * clickActionTR
-            * clickActionML * clickActionMC * clickActionMR
-            * clickActionBL * clickActionBC * clickActionBR != 0
-        ) {
-            appCtx.putPrefInt(PreferKey.clickActionMC, 0)
-            appCtx.toastOnUi("当前没有配置菜单区域,自动恢复中间区域为菜单.")
-        }
-    }
-
-    fun detectMangaClickArea() {
-        ReadMangaConfig.detectMangaClickArea()
-    }
-
     var firebaseEnable: Boolean
         get() = OtherConfig.firebaseEnable
         set(value) {

+ 9 - 7
app/src/main/java/io/legado/app/service/BaseReadAloudService.kt

@@ -37,6 +37,7 @@ import io.legado.app.constant.Status
 import io.legado.app.domain.model.PlaybackTimer
 import io.legado.app.help.MediaHelp
 import io.legado.app.help.config.AppConfig
+import io.legado.app.help.config.AppConfigStore
 import io.legado.app.ui.config.readConfig.ReadConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.help.glide.ImageLoader
@@ -51,13 +52,14 @@ import io.legado.app.utils.LogUtils
 import io.legado.app.utils.activityPendingIntent
 import io.legado.app.utils.getPrefBoolean
 import io.legado.app.utils.observeEvent
-import io.legado.app.utils.observeSharedPreferences
 import io.legado.app.utils.postEvent
 import io.legado.app.utils.toastOnUi
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.Dispatchers.Main
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.drop
+import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 import splitties.init.appCtx
@@ -190,12 +192,12 @@ abstract class BaseReadAloudService : BaseService(),
             val startPos = it.getInt("startPos")
             newReadAloud(play, pageIndex, startPos)
         }
-        observeSharedPreferences { _, key ->
-            when (key) {
-                PreferKey.ignoreAudioFocus,
-                PreferKey.pauseReadAloudWhilePhoneCalls -> {
-                    initPhoneStateListener()
-                }
+        lifecycleScope.launch {
+            merge(
+                AppConfigStore.observeBoolean(PreferKey.ignoreAudioFocus).drop(1),
+                AppConfigStore.observeBoolean(PreferKey.pauseReadAloudWhilePhoneCalls).drop(1),
+            ).collect {
+                initPhoneStateListener()
             }
         }
     }