Horis 2 lat temu
rodzic
commit
b84be6e1b8

+ 23 - 18
app/src/main/java/io/legado/app/service/CacheBookService.kt

@@ -23,6 +23,8 @@ import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
 import splitties.init.appCtx
 import splitties.init.appCtx
 import splitties.systemservices.notificationManager
 import splitties.systemservices.notificationManager
 import java.util.concurrent.Executors
 import java.util.concurrent.Executors
@@ -43,6 +45,7 @@ class CacheBookService : BaseService() {
         Executors.newFixedThreadPool(min(threadCount, AppConst.MAX_THREAD)).asCoroutineDispatcher()
         Executors.newFixedThreadPool(min(threadCount, AppConst.MAX_THREAD)).asCoroutineDispatcher()
     private var downloadJob: Job? = null
     private var downloadJob: Job? = null
     private var notificationContent = appCtx.getString(R.string.service_starting)
     private var notificationContent = appCtx.getString(R.string.service_starting)
+    private var mutex = Mutex()
     private val notificationBuilder by lazy {
     private val notificationBuilder by lazy {
         val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload)
         val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload)
             .setSmallIcon(R.drawable.ic_download)
             .setSmallIcon(R.drawable.ic_download)
@@ -102,27 +105,29 @@ class CacheBookService : BaseService() {
             val chapterCount = appDb.bookChapterDao.getChapterCount(bookUrl)
             val chapterCount = appDb.bookChapterDao.getChapterCount(bookUrl)
             val book = cacheBook.book
             val book = cacheBook.book
             if (chapterCount == 0) {
             if (chapterCount == 0) {
-                val name = book.name
-                if (book.tocUrl.isEmpty()) {
-                    kotlin.runCatching {
-                        WebBook.getBookInfoAwait(cacheBook.bookSource, book)
-                    }.onFailure {
-                        val msg = "《$name》目录为空且加载详情页失败\n${it.localizedMessage}"
-                        AppLog.put(msg, it, true)
-                        return@execute
+                mutex.withLock {
+                    val name = book.name
+                    if (book.tocUrl.isEmpty()) {
+                        kotlin.runCatching {
+                            WebBook.getBookInfoAwait(cacheBook.bookSource, book)
+                        }.onFailure {
+                            val msg = "《$name》目录为空且加载详情页失败\n${it.localizedMessage}"
+                            AppLog.put(msg, it, true)
+                            return@execute
+                        }
                     }
                     }
-                }
-                WebBook.getChapterListAwait(cacheBook.bookSource, book).onFailure {
-                    if (book.totalChapterNum > 0) {
-                        book.totalChapterNum = 0
-                        book.save()
+                    WebBook.getChapterListAwait(cacheBook.bookSource, book).onFailure {
+                        if (book.totalChapterNum > 0) {
+                            book.totalChapterNum = 0
+                            book.save()
+                        }
+                        AppLog.put("《$name》目录为空且加载目录失败\n${it.localizedMessage}", it, true)
+                        return@execute
+                    }.getOrNull()?.let { toc ->
+                        appDb.bookChapterDao.insert(*toc.toTypedArray())
                     }
                     }
-                    AppLog.put("《$name》目录为空且加载目录失败\n${it.localizedMessage}", it, true)
-                    return@execute
-                }.getOrNull()?.let { toc ->
-                    appDb.bookChapterDao.insert(*toc.toTypedArray())
+                    book.save()
                 }
                 }
-                book.save()
             }
             }
             val end2 = if (end < 0) {
             val end2 = if (end < 0) {
                 book.lastChapterIndex
                 book.lastChapterIndex

+ 2 - 8
app/src/main/java/io/legado/app/web/HttpServer.kt

@@ -14,12 +14,8 @@ import io.legado.app.web.utils.AssetsWeb
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.runBlocking
 import okio.Pipe
 import okio.Pipe
 import okio.buffer
 import okio.buffer
-import java.io.BufferedWriter
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.io.ByteArrayOutputStream
-import java.io.OutputStreamWriter
-import kotlin.collections.HashMap
-import kotlin.collections.List
 import kotlin.collections.set
 import kotlin.collections.set
 
 
 class HttpServer(port: Int) : NanoHTTPD(port) {
 class HttpServer(port: Int) : NanoHTTPD(port) {
@@ -115,10 +111,8 @@ class HttpServer(port: Int) : NanoHTTPD(port) {
                 if (data is List<*> && data.size > 3000) {
                 if (data is List<*> && data.size > 3000) {
                     val pipe = Pipe(16 * 1024)
                     val pipe = Pipe(16 * 1024)
                     Coroutine.async {
                     Coroutine.async {
-                        pipe.sink.buffer().outputStream().use { out ->
-                            BufferedWriter(OutputStreamWriter(out, "UTF-8")).use {
-                                GSON.toJson(returnData, it)
-                            }
+                        pipe.sink.buffer().outputStream().bufferedWriter(Charsets.UTF_8).use {
+                            GSON.toJson(returnData, it)
                         }
                         }
                     }
                     }
                     newChunkedResponse(
                     newChunkedResponse(