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

fix: 电量显示卡住及阅读记录丢失

HapeLee 5 месяцев назад
Родитель
Сommit
9a53f9eaf4

+ 25 - 6
app/src/main/java/io/legado/app/model/ReadBook.kt

@@ -109,7 +109,7 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
 
     val executor = globalExecutor
 
-    private val ioScope = CoroutineScope(IO)
+    private val ioScope = CoroutineScope(SupervisorJob() + IO)
 
     private var autoSaveJob: Job? = null
 
@@ -376,27 +376,46 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
     }
 
     fun commitReadSession() {
+        val sessionToCommit = currentActiveSession ?: return
+        currentActiveSession = null
         ioScope.launch {
-            commitSessionInternal()
+            saveSessionToDb(sessionToCommit)
         }
     }
 
     /**
-     * 内部提交逻辑
+     * 内部提交逻辑(auto-save 专用):保存后立即创建新 session 保证连续记录
      */
     private suspend fun commitSessionInternal() {
         val sessionToSave = currentActiveSession ?: return
         val sessionDuration = sessionToSave.endTime - sessionToSave.startTime
         if (sessionDuration < MIN_READ_DURATION) {
-            currentActiveSession = null
             return
         }
         try {
             readRecordRepository.saveReadSession(sessionToSave)
         } catch (e: Exception) {
             AppLog.put("保存阅读会话出错: ${sessionToSave.bookName}", e)
-        } finally {
-            currentActiveSession = null
+            return
+        }
+        // 保存成功后立即创建新 session,避免 auto-save 空窗期
+        currentActiveSession = sessionToSave.copy(
+            startTime = sessionToSave.endTime,
+            endTime = sessionToSave.endTime,
+            words = durChapterIndex.toLong()
+        )
+    }
+
+    /**
+     * 将 session 写入数据库(pause 专用,不重建 session)
+     */
+    private suspend fun saveSessionToDb(session: ReadRecordSession) {
+        val sessionDuration = session.endTime - session.startTime
+        if (sessionDuration < MIN_READ_DURATION) return
+        try {
+            readRecordRepository.saveReadSession(session)
+        } catch (e: Exception) {
+            AppLog.put("保存阅读会话出错: ${session.bookName}", e)
         }
     }
 

+ 5 - 1
app/src/main/java/io/legado/app/ui/book/read/ReadBookController.kt

@@ -11,6 +11,7 @@ import android.view.MotionEvent
 import android.view.View
 import android.view.WindowInsets
 import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
 import androidx.core.view.HapticFeedbackConstantsCompat
 import androidx.core.view.WindowInsetsCompat
 import androidx.core.view.doOnAttach
@@ -1014,7 +1015,10 @@ class ReadBookController(
 
     private fun registerTimeBatteryReceiver() {
         if (timeBatteryReceiverRegistered) return
-        activity.registerReceiver(timeBatteryReceiver, timeBatteryReceiver.filter)
+        ContextCompat.registerReceiver(
+            activity, timeBatteryReceiver, timeBatteryReceiver.filter,
+            ContextCompat.RECEIVER_EXPORTED
+        )
         timeBatteryReceiverRegistered = true
     }
 

+ 5 - 0
app/src/main/java/io/legado/app/ui/book/read/ReadBookRouteScreen.kt

@@ -25,6 +25,7 @@ import com.kyant.backdrop.backdrops.rememberLayerBackdrop
 import dev.chrisbanes.haze.HazeState
 import dev.chrisbanes.haze.hazeSource
 import io.legado.app.R
+import io.legado.app.constant.AppLog
 import io.legado.app.constant.ReadMenuBlurMode
 import io.legado.app.help.IntentData
 import io.legado.app.help.IntentHelp
@@ -235,6 +236,7 @@ fun ReadBookRouteScreen(
         coroutineScope {
             val collector = launch {
                 viewModel.effects.collect { effect ->
+                try {
                     when (effect) {
                         // Launcher-dependent effects — handled directly by route
                         is ReadBookEffect.OpenChapterList -> {
@@ -346,6 +348,9 @@ fun ReadBookRouteScreen(
                         // All other effects — delegate to bridge (View/Window/Activity operations)
                         else -> controller.handleEffect(effect)
                     }
+                } catch (e: Exception) {
+                    AppLog.put("ReadBook effect处理异常: ${effect::class.simpleName}", e)
+                }
                 }
             }
             yield()