优化下载逻辑

This commit is contained in:
HapeLee committed 2026-05-10 23:07:24 +08:00
1 parent c0700231b7
commit 6a0954377a
2 files changed
+45 -15

No files matched your search

@@ -1,6 +1,8 @@
package io.legado.app.model package io.legado.app.model
import android.content.Context import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat
import io.legado.app.constant.IntentAction import io.legado.app.constant.IntentAction
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
@@ -12,8 +14,8 @@ import io.legado.app.model.cache.CacheDownloadStateStore
import io.legado.app.model.cache.ChapterSelection import io.legado.app.model.cache.ChapterSelection
import io.legado.app.service.CacheBookService import io.legado.app.service.CacheBookService
import io.legado.app.ui.config.otherConfig.OtherConfig import io.legado.app.ui.config.otherConfig.OtherConfig
import io.legado.app.utils.LogUtils
import io.legado.app.utils.onEachParallel import io.legado.app.utils.onEachParallel
import io.legado.app.utils.startService
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
@@ -233,7 +235,7 @@ object CacheBook {
if (isLocal) return if (isLocal) return
if (!request.hasValidSelection()) return if (!request.hasValidSelection()) return
isPaused = false isPaused = false
context.startService<CacheBookService> { startCacheBookService(context) {
action = IntentAction.start action = IntentAction.start
putRequestExtras(request) putRequestExtras(request)
} }
@@ -247,7 +249,7 @@ object CacheBook {
} }
.forEach { request -> .forEach { request ->
isPaused = false isPaused = false
context.startService<CacheBookService> { startCacheBookService(context) {
action = IntentAction.start action = IntentAction.start
putRequestExtras(request) putRequestExtras(request)
} }
@@ -272,15 +274,29 @@ object CacheBook {
} }
} }
private fun startCacheBookService(context: Context, configIntent: Intent.() -> Unit = {}): Boolean {
val intent = Intent(context, CacheBookService::class.java).apply(configIntent)
return try {
ContextCompat.startForegroundService(context, intent)
true
} catch (e: Exception) {
LogUtils.e("CacheBook", "启动下载服务失败: ${e.localizedMessage}")
false
}
}
fun remove(context: Context, bookUrl: String) { fun remove(context: Context, bookUrl: String) {
if (!CacheBookService.isRun) { if (!CacheBookService.isRun) {
removeBookFromService(bookUrl) removeBookFromService(bookUrl)
return return
} }
context.startService<CacheBookService> { val started = startCacheBookService(context) {
action = IntentAction.remove action = IntentAction.remove
putExtra("bookUrl", bookUrl) putExtra("bookUrl", bookUrl)
} }
if (!started) {
removeBookFromService(bookUrl)
}
} }
suspend fun removeAwait(context: Context, bookUrl: String): Boolean { suspend fun removeAwait(context: Context, bookUrl: String): Boolean {
@@ -290,15 +306,14 @@ object CacheBook {
val requestId = pendingRequestId.incrementAndGet() val requestId = pendingRequestId.incrementAndGet()
val removeRequest = CompletableDeferred<Boolean>() val removeRequest = CompletableDeferred<Boolean>()
pendingRemoveRequests[requestId] = removeRequest pendingRemoveRequests[requestId] = removeRequest
runCatching { val started = startCacheBookService(context) {
context.startService<CacheBookService> {
action = IntentAction.remove action = IntentAction.remove
putExtra("bookUrl", bookUrl) putExtra("bookUrl", bookUrl)
putExtra("removeRequestId", requestId) putExtra("removeRequestId", requestId)
} }
}.onFailure { if (!started) {
pendingRemoveRequests.remove(requestId) pendingRemoveRequests.remove(requestId)
removeRequest.completeExceptionally(it) return removeBookFromService(bookUrl)
} }
return try { return try {
withTimeout(30_000L) { withTimeout(30_000L) {
@@ -340,17 +355,23 @@ object CacheBook {
fun stop(context: Context) { fun stop(context: Context) {
if (CacheBookService.isRun) { if (CacheBookService.isRun) {
context.startService<CacheBookService> { val started = startCacheBookService(context) {
action = IntentAction.stop action = IntentAction.stop
} }
if (!started) {
close(clearFailureState = false)
}
} }
} }
fun pause(context: Context) { fun pause(context: Context) {
if (CacheBookService.isRun) { if (CacheBookService.isRun) {
context.startService<CacheBookService> { val started = startCacheBookService(context) {
action = IntentAction.pause action = IntentAction.pause
} }
if (!started) {
pauseAllFromService()
}
} else { } else {
pauseAllFromService() pauseAllFromService()
} }
@@ -359,9 +380,12 @@ object CacheBook {
fun resume(context: Context): Boolean { fun resume(context: Context): Boolean {
if (!hasQueuedDownloads) return false if (!hasQueuedDownloads) return false
isPaused = false isPaused = false
context.startService<CacheBookService> { val started = startCacheBookService(context) {
action = IntentAction.resume action = IntentAction.resume
} }
if (!started) {
resumeFromService()
}
return true return true
} }
@@ -399,9 +423,12 @@ object CacheBook {
isPaused = false isPaused = false
updateSummary() updateSummary()
_queueChangedFlow.tryEmit(bookUrl) _queueChangedFlow.tryEmit(bookUrl)
context.startService<CacheBookService> { val started = startCacheBookService(context) {
action = IntentAction.resume action = IntentAction.resume
} }
if (!started) {
resumeFromService()
}
} }
return resumed return resumed
} }
@@ -421,9 +448,12 @@ object CacheBook {
isPaused = false isPaused = false
updateSummary() updateSummary()
_queueChangedFlow.tryEmit(bookUrl) _queueChangedFlow.tryEmit(bookUrl)
context.startService<CacheBookService> { val started = startCacheBookService(context) {
action = IntentAction.resume action = IntentAction.resume
} }
if (!started) {
resumeFromService()
}
} }
return resumed return resumed
} }
@@ -170,9 +170,9 @@ inline fun <reified T : BroadcastReceiver> Context.broadcastPendingIntent(
fun Context.startForegroundServiceCompat(intent: Intent) { fun Context.startForegroundServiceCompat(intent: Intent) {
try { try {
startService(intent)
} catch (e: IllegalStateException) {
ContextCompat.startForegroundService(this, intent) ContextCompat.startForegroundService(this, intent)
} catch (e: Exception) {
startService(intent)
} }
} }