From a5c6e6f7dcefc2fa497f19acfd357c552aec0c99 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 30 Sep 2021 09:33:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/model/CacheBook.kt | 433 +++++++++--------- 1 file changed, 217 insertions(+), 216 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/CacheBook.kt b/app/src/main/java/io/legado/app/model/CacheBook.kt index 4d41658f2..6bca836ec 100644 --- a/app/src/main/java/io/legado/app/model/CacheBook.kt +++ b/app/src/main/java/io/legado/app/model/CacheBook.kt @@ -19,269 +19,270 @@ import kotlinx.coroutines.delay import java.util.concurrent.ConcurrentHashMap import kotlin.coroutines.CoroutineContext -class CacheBook(var bookSource: BookSource, var book: Book) { +object CacheBook { - companion object { + val cacheBookMap = ConcurrentHashMap() - val cacheBookMap = ConcurrentHashMap() - - @Synchronized - fun getOrCreate(bookUrl: String): CacheBook? { - val book = appDb.bookDao.getBook(bookUrl) ?: return null - val bookSource = appDb.bookSourceDao.getBookSource(book.origin) ?: return null - var cacheBook = cacheBookMap[bookUrl] - if (cacheBook != null) { - //存在时更新,书源可能会变化,必须更新 - cacheBook.bookSource = bookSource - cacheBook.book = book - return cacheBook - } - cacheBook = CacheBook(bookSource, book) - cacheBookMap[bookUrl] = cacheBook + @Synchronized + fun getOrCreate(bookUrl: String): CacheBookModel? { + val book = appDb.bookDao.getBook(bookUrl) ?: return null + val bookSource = appDb.bookSourceDao.getBookSource(book.origin) ?: return null + var cacheBook = cacheBookMap[bookUrl] + if (cacheBook != null) { + //存在时更新,书源可能会变化,必须更新 + cacheBook.bookSource = bookSource + cacheBook.book = book return cacheBook } + cacheBook = CacheBookModel(bookSource, book) + cacheBookMap[bookUrl] = cacheBook + return cacheBook + } - @Synchronized - fun getOrCreate(bookSource: BookSource, book: Book): CacheBook { - var cacheBook = cacheBookMap[book.bookUrl] - if (cacheBook != null) { - //存在时更新,书源可能会变化,必须更新 - cacheBook.bookSource = bookSource - cacheBook.book = book - return cacheBook - } - cacheBook = CacheBook(bookSource, book) - cacheBookMap[book.bookUrl] = cacheBook + @Synchronized + fun getOrCreate(bookSource: BookSource, book: Book): CacheBookModel { + var cacheBook = cacheBookMap[book.bookUrl] + if (cacheBook != null) { + //存在时更新,书源可能会变化,必须更新 + cacheBook.bookSource = bookSource + cacheBook.book = book return cacheBook } + cacheBook = CacheBookModel(bookSource, book) + cacheBookMap[book.bookUrl] = cacheBook + return cacheBook + } - fun start(context: Context, bookUrl: String, start: Int, end: Int) { - context.startService { - action = IntentAction.start - putExtra("bookUrl", bookUrl) - putExtra("start", start) - putExtra("end", end) - } + fun start(context: Context, bookUrl: String, start: Int, end: Int) { + context.startService { + action = IntentAction.start + putExtra("bookUrl", bookUrl) + putExtra("start", start) + putExtra("end", end) } + } - fun remove(context: Context, bookUrl: String) { - context.startService { - action = IntentAction.remove - putExtra("bookUrl", bookUrl) - } + fun remove(context: Context, bookUrl: String) { + context.startService { + action = IntentAction.remove + putExtra("bookUrl", bookUrl) } + } - fun stop(context: Context) { - context.startService { - action = IntentAction.stop - } + fun stop(context: Context) { + context.startService { + action = IntentAction.stop } + } - val downloadSummary: String - get() { - return "正在下载:${onDownloadCount}|等待中:${waitCount}|失败:${errorCount}|成功:${successCount}" - } + val downloadSummary: String + get() { + return "正在下载:${onDownloadCount}|等待中:${waitCount}|失败:${errorCount}|成功:${successCount}" + } - val isRun: Boolean - get() { - var isRun = false - cacheBookMap.forEach { - isRun = isRun || it.value.isRun() - } - return isRun + val isRun: Boolean + get() { + var isRun = false + cacheBookMap.forEach { + isRun = isRun || it.value.isRun() } + return isRun + } - private val waitCount: Int - get() { - var count = 0 - cacheBookMap.forEach { - count += it.value.waitCount - } - return count + private val waitCount: Int + get() { + var count = 0 + cacheBookMap.forEach { + count += it.value.waitCount } + return count + } - private val successCount: Int - get() { - var count = 0 - cacheBookMap.forEach { - count += it.value.successCount - } - return count + private val successCount: Int + get() { + var count = 0 + cacheBookMap.forEach { + count += it.value.successCount } + return count + } - val onDownloadCount: Int - get() { - var count = 0 - cacheBookMap.forEach { - count += it.value.onDownloadCount - } - return count + val onDownloadCount: Int + get() { + var count = 0 + cacheBookMap.forEach { + count += it.value.onDownloadCount } + return count + } - private val errorCount: Int - get() { - var count = 0 - cacheBookMap.forEach { - count += it.value.errorCount - } - return count + private val errorCount: Int + get() { + var count = 0 + cacheBookMap.forEach { + count += it.value.errorCount } - } - - private val waitDownloadSet = hashSetOf() - private val onDownloadSet = hashSetOf() - private val successDownloadSet = hashSetOf() - private val errorDownloadMap = hashMapOf() + return count + } - val waitCount get() = waitDownloadSet.size - val onDownloadCount get() = onDownloadSet.size - val successCount get() = successDownloadSet.size - val errorCount get() = errorDownloadMap.size + class CacheBookModel(var bookSource: BookSource, var book: Book) { - @Synchronized - fun isRun(): Boolean { - return waitDownloadSet.size > 0 || onDownloadSet.size > 0 - } + private val waitDownloadSet = hashSetOf() + private val onDownloadSet = hashSetOf() + private val successDownloadSet = hashSetOf() + private val errorDownloadMap = hashMapOf() - @Synchronized - fun stop() { - waitDownloadSet.clear() - } + val waitCount get() = waitDownloadSet.size + val onDownloadCount get() = onDownloadSet.size + val successCount get() = successDownloadSet.size + val errorCount get() = errorDownloadMap.size - @Synchronized - fun addDownload(start: Int, end: Int) { - for (i in start..end) { - if (!onDownloadSet.contains(i)) { - waitDownloadSet.add(i) - } + @Synchronized + fun isRun(): Boolean { + return waitDownloadSet.size > 0 || onDownloadSet.size > 0 } - } - @Synchronized - private fun onSuccess(index: Int) { - onDownloadSet.remove(index) - successDownloadSet.add(index) - errorDownloadMap.remove(index) - } + @Synchronized + fun stop() { + waitDownloadSet.clear() + } - @Synchronized - private fun onError(index: Int, error: Throwable, chapterTitle: String) { - if (error !is ConcurrentException) { - errorDownloadMap[index] = (errorDownloadMap[index] ?: 0) + 1 + @Synchronized + fun addDownload(start: Int, end: Int) { + for (i in start..end) { + if (!onDownloadSet.contains(i)) { + waitDownloadSet.add(i) + } + } } - onDownloadSet.remove(index) - //重试3次 - if (errorDownloadMap[index] ?: 0 < 3) { - waitDownloadSet.add(index) - } else { - AppLog.addLog( - "下载${book.name}-${chapterTitle}失败\n${error.localizedMessage}", - error - ) - error.printOnDebug() + + @Synchronized + private fun onSuccess(index: Int) { + onDownloadSet.remove(index) + successDownloadSet.add(index) + errorDownloadMap.remove(index) } - } - @Synchronized - private fun onCancel(index: Int) { - onDownloadSet.remove(index) - waitDownloadSet.add(index) - } + @Synchronized + private fun onError(index: Int, error: Throwable, chapterTitle: String) { + if (error !is ConcurrentException) { + errorDownloadMap[index] = (errorDownloadMap[index] ?: 0) + 1 + } + onDownloadSet.remove(index) + //重试3次 + if (errorDownloadMap[index] ?: 0 < 3) { + waitDownloadSet.add(index) + } else { + AppLog.addLog( + "下载${book.name}-${chapterTitle}失败\n${error.localizedMessage}", + error + ) + error.printOnDebug() + } + } - @Synchronized - private fun onFinally() { - if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { - postEvent(EventBus.UP_DOWNLOAD, "") - cacheBookMap.remove(book.bookUrl) + @Synchronized + private fun onCancel(index: Int) { + onDownloadSet.remove(index) + waitDownloadSet.add(index) } - } - /** - * 从待下载列表内取第一条下载 - */ - @Synchronized - fun download(scope: CoroutineScope, context: CoroutineContext): Boolean { - val chapterIndex = waitDownloadSet.firstOrNull() - if (chapterIndex == null) { - if (onDownloadSet.isEmpty()) { + @Synchronized + private fun onFinally() { + if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { + postEvent(EventBus.UP_DOWNLOAD, "") cacheBookMap.remove(book.bookUrl) } - return false - } - if (onDownloadSet.contains(chapterIndex)) { - waitDownloadSet.remove(chapterIndex) - return download(scope, context) - } - val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, chapterIndex) ?: let { - waitDownloadSet.remove(chapterIndex) - return download(scope, context) - } - if (BookHelp.hasContent(book, chapter)) { - waitDownloadSet.remove(chapterIndex) - return download(scope, context) - } - waitDownloadSet.remove(chapterIndex) - onDownloadSet.add(chapterIndex) - WebBook.getContent( - scope, - bookSource, - book, - chapter, - context = context - ).onSuccess { content -> - onSuccess(chapterIndex) - downloadFinish(chapter, content) - }.onError { - //出现错误等待一秒后重新加入待下载列表 - delay(1000) - onError(chapterIndex, it, chapter.title) - downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}") - }.onCancel { - onCancel(chapterIndex) - }.onFinally { - onFinally() } - return true - } - @Synchronized - fun download( - scope: CoroutineScope, - chapter: BookChapter, - resetPageOffset: Boolean = false - ) { - if (onDownloadSet.contains(chapter.index)) { - return - } - onDownloadSet.add(chapter.index) - waitDownloadSet.remove(chapter.index) - WebBook.getContent(scope, bookSource, book, chapter) - .onSuccess { content -> - onSuccess(chapter.index) - downloadFinish(chapter, content, resetPageOffset) + /** + * 从待下载列表内取第一条下载 + */ + @Synchronized + fun download(scope: CoroutineScope, context: CoroutineContext): Boolean { + val chapterIndex = waitDownloadSet.firstOrNull() + if (chapterIndex == null) { + if (onDownloadSet.isEmpty()) { + cacheBookMap.remove(book.bookUrl) + } + return false + } + if (onDownloadSet.contains(chapterIndex)) { + waitDownloadSet.remove(chapterIndex) + return download(scope, context) + } + val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, chapterIndex) ?: let { + waitDownloadSet.remove(chapterIndex) + return download(scope, context) + } + if (BookHelp.hasContent(book, chapter)) { + waitDownloadSet.remove(chapterIndex) + return download(scope, context) + } + waitDownloadSet.remove(chapterIndex) + onDownloadSet.add(chapterIndex) + WebBook.getContent( + scope, + bookSource, + book, + chapter, + context = context + ).onSuccess { content -> + onSuccess(chapterIndex) + downloadFinish(chapter, content) }.onError { - onError(chapter.index, it, chapter.title) - downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}", resetPageOffset) + //出现错误等待一秒后重新加入待下载列表 + delay(1000) + onError(chapterIndex, it, chapter.title) + downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}") }.onCancel { - onCancel(chapter.index) + onCancel(chapterIndex) }.onFinally { - if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { - postEvent(EventBus.UP_DOWNLOAD, "") - } + onFinally() } - } + return true + } - private fun downloadFinish( - chapter: BookChapter, - content: String, - resetPageOffset: Boolean = false - ) { - if (ReadBook.book?.bookUrl == book.bookUrl) { - ReadBook.contentLoadFinish( - book, chapter, content, - resetPageOffset = resetPageOffset - ) + @Synchronized + fun download( + scope: CoroutineScope, + chapter: BookChapter, + resetPageOffset: Boolean = false + ) { + if (onDownloadSet.contains(chapter.index)) { + return + } + onDownloadSet.add(chapter.index) + waitDownloadSet.remove(chapter.index) + WebBook.getContent(scope, bookSource, book, chapter) + .onSuccess { content -> + onSuccess(chapter.index) + downloadFinish(chapter, content, resetPageOffset) + }.onError { + onError(chapter.index, it, chapter.title) + downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}", resetPageOffset) + }.onCancel { + onCancel(chapter.index) + }.onFinally { + if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { + postEvent(EventBus.UP_DOWNLOAD, "") + } + } } + + private fun downloadFinish( + chapter: BookChapter, + content: String, + resetPageOffset: Boolean = false + ) { + if (ReadBook.book?.bookUrl == book.bookUrl) { + ReadBook.contentLoadFinish( + book, chapter, content, + resetPageOffset = resetPageOffset + ) + } + } + } } \ No newline at end of file