|
|
@ -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, |
|
|
|