优化下载

pull/1298/head
gedoor 3 years ago
parent 4089b59e15
commit 6205e00e55
  1. 49
      app/src/main/java/io/legado/app/model/CacheBook.kt
  2. 2
      app/src/main/java/io/legado/app/service/CacheBookService.kt

@ -17,7 +17,6 @@ import kotlinx.coroutines.CoroutineScope
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArraySet
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
class CacheBook(val bookSource: BookSource, val book: Book) { class CacheBook(val bookSource: BookSource, val book: Book) {
@ -117,22 +116,40 @@ class CacheBook(val bookSource: BookSource, val book: Book) {
} }
val waitDownloadSet = CopyOnWriteArraySet<Int>() val waitDownloadSet = hashSetOf<Int>()
val onDownloadSet = CopyOnWriteArraySet<Int>() val onDownloadSet = hashSetOf<Int>()
val successDownloadSet = CopyOnWriteArraySet<Int>() val successDownloadSet = hashSetOf<Int>()
fun addDownload(start: Int, end: Int) { fun addDownload(start: Int, end: Int) {
synchronized(this) {
for (i in start..end) { for (i in start..end) {
waitDownloadSet.add(i) waitDownloadSet.add(i)
} }
} }
}
fun isRun(): Boolean { fun isRun(): Boolean {
return waitDownloadSet.size > 0 || onDownloadSet.size > 0 return synchronized(this) {
waitDownloadSet.size > 0 || onDownloadSet.size > 0
}
}
private fun onSuccess(index: Int) {
synchronized(this) {
onDownloadSet.remove(index)
successDownloadSet.add(index)
}
}
private fun onErrorOrCancel(index: Int) {
synchronized(this) {
onDownloadSet.remove(index)
waitDownloadSet.add(index)
}
} }
@Synchronized
fun download(scope: CoroutineScope, context: CoroutineContext): Boolean { fun download(scope: CoroutineScope, context: CoroutineContext): Boolean {
synchronized(this) {
val chapterIndex = waitDownloadSet.firstOrNull() ?: return false val chapterIndex = waitDownloadSet.firstOrNull() ?: return false
if (onDownloadSet.contains(chapterIndex)) { if (onDownloadSet.contains(chapterIndex)) {
waitDownloadSet.remove(chapterIndex) waitDownloadSet.remove(chapterIndex)
@ -155,19 +172,16 @@ class CacheBook(val bookSource: BookSource, val book: Book) {
chapter, chapter,
context = context context = context
).onSuccess { content -> ).onSuccess { content ->
onDownloadSet.remove(chapterIndex) onSuccess(chapterIndex)
successDownloadSet.add(chapterIndex)
addLog("${book.name}-${chapter.title} getContentSuccess") addLog("${book.name}-${chapter.title} getContentSuccess")
downloadFinish(chapter, content.ifBlank { "No content" }) downloadFinish(chapter, content.ifBlank { "No content" })
}.onError { }.onError {
onDownloadSet.remove(chapterIndex) onErrorOrCancel(chapterIndex)
waitDownloadSet.add(chapterIndex)
print(it.localizedMessage) print(it.localizedMessage)
addLog("${book.name}-${chapter.title} getContentError${it.localizedMessage}") addLog("${book.name}-${chapter.title} getContentError${it.localizedMessage}")
downloadFinish(chapter, it.localizedMessage ?: "download error") downloadFinish(chapter, it.localizedMessage ?: "download error")
}.onCancel { }.onCancel {
onDownloadSet.remove(chapterIndex) onErrorOrCancel(chapterIndex)
waitDownloadSet.add(chapterIndex)
}.onFinally { }.onFinally {
if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) {
postEvent(EventBus.UP_DOWNLOAD, "") postEvent(EventBus.UP_DOWNLOAD, "")
@ -175,6 +189,7 @@ class CacheBook(val bookSource: BookSource, val book: Book) {
} }
return true return true
} }
}
@Synchronized @Synchronized
fun download( fun download(
@ -182,6 +197,7 @@ class CacheBook(val bookSource: BookSource, val book: Book) {
chapter: BookChapter, chapter: BookChapter,
resetPageOffset: Boolean = false resetPageOffset: Boolean = false
) { ) {
synchronized(this) {
if (onDownloadSet.contains(chapter.index)) { if (onDownloadSet.contains(chapter.index)) {
return return
} }
@ -190,12 +206,19 @@ class CacheBook(val bookSource: BookSource, val book: Book) {
.onSuccess { content -> .onSuccess { content ->
downloadFinish(chapter, content.ifBlank { "No content" }, resetPageOffset) downloadFinish(chapter, content.ifBlank { "No content" }, resetPageOffset)
}.onError { }.onError {
downloadFinish(chapter, it.localizedMessage ?: "download error", resetPageOffset) downloadFinish(
chapter,
it.localizedMessage ?: "download error",
resetPageOffset
)
}.onFinally { }.onFinally {
synchronized(this) {
onDownloadSet.remove(chapter.index) onDownloadSet.remove(chapter.index)
}
ReadBook.removeLoading(chapter.index) ReadBook.removeLoading(chapter.index)
} }
} }
}
private fun downloadFinish( private fun downloadFinish(
chapter: BookChapter, chapter: BookChapter,

@ -92,7 +92,7 @@ class CacheBookService : BaseService() {
while (isActive) { while (isActive) {
CacheBook.cacheBookMap.forEach { CacheBook.cacheBookMap.forEach {
while (CacheBook.onDownloadCount > threadCount) { while (CacheBook.onDownloadCount > threadCount) {
delay(50) delay(100)
} }
it.value.download(this, cachePool) it.value.download(this, cachePool)
} }

Loading…
Cancel
Save