Horis 2 ani în urmă
părinte
comite
004c5dbbac

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

@@ -29,6 +29,8 @@ import kotlinx.coroutines.cancelChildren
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import splitties.init.appCtx
 import splitties.init.appCtx
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
 import kotlin.math.min
 import kotlin.math.min
 
 
 
 
@@ -63,6 +65,7 @@ object ReadBook : CoroutineScope by MainScope() {
     val downloadFailChapters = hashMapOf<Int, Int>()
     val downloadFailChapters = hashMapOf<Int, Int>()
     var contentProcessor: ContentProcessor? = null
     var contentProcessor: ContentProcessor? = null
     val downloadScope = CoroutineScope(SupervisorJob() + IO)
     val downloadScope = CoroutineScope(SupervisorJob() + IO)
+    val executor: ExecutorService = Executors.newSingleThreadExecutor()
 
 
     //暂时保存跳转前进度
     //暂时保存跳转前进度
     fun saveCurrentBookProcess() {
     fun saveCurrentBookProcess() {
@@ -158,10 +161,10 @@ object ReadBook : CoroutineScope by MainScope() {
     }
     }
 
 
     fun upReadTime() {
     fun upReadTime() {
-        if (!AppConfig.enableReadRecord) {
-            return
-        }
-        Coroutine.async(executeContext = IO) {
+        executor.execute {
+            if (!AppConfig.enableReadRecord) {
+                return@execute
+            }
             readRecord.readTime = readRecord.readTime + System.currentTimeMillis() - readStartTime
             readRecord.readTime = readRecord.readTime + System.currentTimeMillis() - readStartTime
             readStartTime = System.currentTimeMillis()
             readStartTime = System.currentTimeMillis()
             readRecord.lastRead = System.currentTimeMillis()
             readRecord.lastRead = System.currentTimeMillis()
@@ -536,8 +539,8 @@ object ReadBook : CoroutineScope by MainScope() {
     }
     }
 
 
     fun saveRead(pageChanged: Boolean = false) {
     fun saveRead(pageChanged: Boolean = false) {
-        Coroutine.async(executeContext = IO) {
-            val book = book ?: return@async
+        executor.execute {
+            val book = book ?: return@execute
             book.lastCheckCount = 0
             book.lastCheckCount = 0
             book.durChapterTime = System.currentTimeMillis()
             book.durChapterTime = System.currentTimeMillis()
             val chapterChanged = book.durChapterIndex != durChapterIndex
             val chapterChanged = book.durChapterIndex != durChapterIndex
@@ -560,26 +563,29 @@ object ReadBook : CoroutineScope by MainScope() {
      */
      */
     private fun preDownload() {
     private fun preDownload() {
         if (book?.isLocal == true) return
         if (book?.isLocal == true) return
-        if (AppConfig.preDownloadNum < 2) {
-            return
-        }
-        preDownloadTask?.cancel()
-        preDownloadTask = Coroutine.async(executeContext = IO) {
-            //预下载
-            launch {
-                val maxChapterIndex = min(durChapterIndex + AppConfig.preDownloadNum, chapterSize)
-                for (i in durChapterIndex.plus(2)..maxChapterIndex) {
-                    if (downloadedChapters.contains(i)) continue
-                    if ((downloadFailChapters[i] ?: 0) >= 3) continue
-                    downloadIndex(i)
-                }
+        executor.execute {
+            if (AppConfig.preDownloadNum < 2) {
+                return@execute
             }
             }
-            launch {
-                val minChapterIndex = durChapterIndex - min(5, AppConfig.preDownloadNum)
-                for (i in durChapterIndex.minus(2) downTo minChapterIndex) {
-                    if (downloadedChapters.contains(i)) continue
-                    if ((downloadFailChapters[i] ?: 0) >= 3) continue
-                    downloadIndex(i)
+            preDownloadTask?.cancel()
+            preDownloadTask = Coroutine.async(executeContext = IO) {
+                //预下载
+                launch {
+                    val maxChapterIndex =
+                        min(durChapterIndex + AppConfig.preDownloadNum, chapterSize)
+                    for (i in durChapterIndex.plus(2)..maxChapterIndex) {
+                        if (downloadedChapters.contains(i)) continue
+                        if ((downloadFailChapters[i] ?: 0) >= 3) continue
+                        downloadIndex(i)
+                    }
+                }
+                launch {
+                    val minChapterIndex = durChapterIndex - min(5, AppConfig.preDownloadNum)
+                    for (i in durChapterIndex.minus(2) downTo minChapterIndex) {
+                        if (downloadedChapters.contains(i)) continue
+                        if ((downloadFailChapters[i] ?: 0) >= 3) continue
+                        downloadIndex(i)
+                    }
                 }
                 }
             }
             }
         }
         }

+ 5 - 4
app/src/main/java/io/legado/app/service/HttpReadAloudService.kt

@@ -91,7 +91,7 @@ class HttpReadAloudService : BaseReadAloudService(),
         playIndexJob?.cancel()
         playIndexJob?.cancel()
     }
     }
 
 
-    private fun playNext() {
+    private fun updateNextPos() {
         readAloudNumber += contentList[nowSpeak].length + 1 - paragraphStartPos
         readAloudNumber += contentList[nowSpeak].length + 1 - paragraphStartPos
         paragraphStartPos = 0
         paragraphStartPos = 0
         if (nowSpeak < contentList.lastIndex) {
         if (nowSpeak < contentList.lastIndex) {
@@ -355,14 +355,14 @@ class HttpReadAloudService : BaseReadAloudService(),
             Player.STATE_ENDED -> {
             Player.STATE_ENDED -> {
                 // 结束
                 // 结束
                 playErrorNo = 0
                 playErrorNo = 0
-                playNext()
+                updateNextPos()
             }
             }
         }
         }
     }
     }
 
 
     override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
     override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
         if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED) return
         if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED) return
-        playNext()
+        updateNextPos()
         upPlayPos()
         upPlayPos()
     }
     }
 
 
@@ -375,7 +375,8 @@ class HttpReadAloudService : BaseReadAloudService(),
             AppLog.put("朗读连续5次错误, 最后一次错误代码(${error.localizedMessage})", error)
             AppLog.put("朗读连续5次错误, 最后一次错误代码(${error.localizedMessage})", error)
             ReadAloud.pause(this)
             ReadAloud.pause(this)
         } else {
         } else {
-            playNext()
+            updateNextPos()
+            exoPlayer.seekToNextMediaItem()
         }
         }
     }
     }
 
 

+ 1 - 2
app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt

@@ -191,7 +191,6 @@ class ReadBookActivity : BaseReadBookActivity(),
     }
     }
     private var menu: Menu? = null
     private var menu: Menu? = null
     private var backupJob: Job? = null
     private var backupJob: Job? = null
-    private var keepScreenJon: Job? = null
     private var tts: TTS? = null
     private var tts: TTS? = null
     val textActionMenu: TextActionMenu by lazy {
     val textActionMenu: TextActionMenu by lazy {
         TextActionMenu(this, this)
         TextActionMenu(this, this)
@@ -221,7 +220,7 @@ class ReadBookActivity : BaseReadBookActivity(),
     private var reloadContent = false
     private var reloadContent = false
     private val handler by lazy { buildMainHandler() }
     private val handler by lazy { buildMainHandler() }
     private val screenOffRunnable by lazy { Runnable { keepScreenOn(false) } }
     private val screenOffRunnable by lazy { Runnable { keepScreenOn(false) } }
-    private val executor = IO.asExecutor()
+    private val executor = ReadBook.executor
 
 
     //恢复跳转前进度对话框的交互结果
     //恢复跳转前进度对话框的交互结果
     private var confirmRestoreProcess: Boolean? = null
     private var confirmRestoreProcess: Boolean? = null

+ 23 - 14
app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt

@@ -380,6 +380,8 @@ object ChapterProvider {
             textLine.addColumn(
             textLine.addColumn(
                 ImageColumn(start = x + start, end = x + end, src = src)
                 ImageColumn(start = x + start, end = x + end, src = src)
             )
             )
+            calcTextLinePosition(textPages, textLine, stringBuilder.length)
+            stringBuilder.append(" ") // 确保翻页时索引计算正确
             textPages.last().addLine(textLine)
             textPages.last().addLine(textLine)
         }
         }
         return absStartX to durY + textHeight * paragraphSpacing / 10f
         return absStartX to durY + textHeight * paragraphSpacing / 10f
@@ -519,24 +521,11 @@ object ChapterProvider {
             if (doublePage) {
             if (doublePage) {
                 textLine.isLeftLine = absStartX < viewWidth / 2
                 textLine.isLeftLine = absStartX < viewWidth / 2
             }
             }
-            val sbLength = stringBuilder.length
+            calcTextLinePosition(textPages, textLine, stringBuilder.length)
             stringBuilder.append(lineText)
             stringBuilder.append(lineText)
             if (textLine.isParagraphEnd) {
             if (textLine.isParagraphEnd) {
                 stringBuilder.append("\n")
                 stringBuilder.append("\n")
             }
             }
-            val lastLine = textPages.last().lines.lastOrNull { it.paragraphNum > 0 }
-                ?: textPages.getOrNull(textPages.lastIndex - 1)?.lines?.lastOrNull { it.paragraphNum > 0 }
-            val paragraphNum = when {
-                lastLine == null -> 1
-                lastLine.isParagraphEnd -> lastLine.paragraphNum + 1
-                else -> lastLine.paragraphNum
-            }
-            textLine.paragraphNum = paragraphNum
-            textLine.chapterPosition =
-                (textPages.getOrNull(textPages.lastIndex - 1)?.lines?.lastOrNull()?.run {
-                    chapterPosition + charSize + if (isParagraphEnd) 1 else 0
-                } ?: 0) + sbLength
-            textLine.pagePosition = sbLength
             textLine.upTopBottom(durY, textHeight, fontMetrics)
             textLine.upTopBottom(durY, textHeight, fontMetrics)
             val textPage = textPages.last()
             val textPage = textPages.last()
             textPage.addLine(textLine)
             textPage.addLine(textLine)
@@ -549,6 +538,26 @@ object ChapterProvider {
         return Pair(absStartX, durY)
         return Pair(absStartX, durY)
     }
     }
 
 
+    private fun calcTextLinePosition(
+        textPages: ArrayList<TextPage>,
+        textLine: TextLine,
+        sbLength: Int
+    ) {
+        val lastLine = textPages.last().lines.lastOrNull { it.paragraphNum > 0 }
+            ?: textPages.getOrNull(textPages.lastIndex - 1)?.lines?.lastOrNull { it.paragraphNum > 0 }
+        val paragraphNum = when {
+            lastLine == null -> 1
+            lastLine.isParagraphEnd -> lastLine.paragraphNum + 1
+            else -> lastLine.paragraphNum
+        }
+        textLine.paragraphNum = paragraphNum
+        textLine.chapterPosition =
+            (textPages.getOrNull(textPages.lastIndex - 1)?.lines?.lastOrNull()?.run {
+                chapterPosition + charSize + if (isParagraphEnd) 1 else 0
+            } ?: 0) + sbLength
+        textLine.pagePosition = sbLength
+    }
+
     /**
     /**
      * 有缩进,两端对齐
      * 有缩进,两端对齐
      */
      */