diff --git a/app/src/main/java/io/legado/app/service/help/CacheBook.kt b/app/src/main/java/io/legado/app/service/help/CacheBook.kt index f2748826a..149e6258c 100644 --- a/app/src/main/java/io/legado/app/service/help/CacheBook.kt +++ b/app/src/main/java/io/legado/app/service/help/CacheBook.kt @@ -2,12 +2,22 @@ package io.legado.app.service.help import android.content.Context import android.content.Intent +import io.legado.app.App +import io.legado.app.R import io.legado.app.constant.IntentAction +import io.legado.app.data.entities.Book +import io.legado.app.data.entities.BookChapter +import io.legado.app.help.BookHelp +import io.legado.app.model.webBook.WebBook import io.legado.app.service.CacheBookService +import io.legado.app.utils.msg +import kotlinx.coroutines.Dispatchers.IO +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArraySet object CacheBook { - val logs = arrayListOf() + private val downloadMap = ConcurrentHashMap>() fun addLog(log: String?) { log ?: return @@ -44,4 +54,52 @@ object CacheBook { } } + fun download( + webBook: WebBook, + book: Book, + chapter: BookChapter, + resetPageOffset: Boolean = false + ) { + if (downloadMap[book.bookUrl]?.contains(chapter.index) == true) { + return + } + if (downloadMap[book.bookUrl] == null) { + downloadMap[book.bookUrl] = CopyOnWriteArraySet() + } + downloadMap[book.bookUrl]?.add(chapter.index) + webBook.getContent(book, chapter) + .onSuccess(IO) { content -> + if (ReadBook.book?.bookUrl == book.bookUrl) { + if (content.isEmpty()) { + ReadBook.contentLoadFinish( + book, + chapter, + App.INSTANCE.getString(R.string.content_empty), + resetPageOffset = resetPageOffset + ) + } else { + BookHelp.saveContent(book, chapter, content) + ReadBook.contentLoadFinish( + book, + chapter, + content, + resetPageOffset = resetPageOffset + ) + } + } + }.onError { + if (ReadBook.book?.bookUrl == book.bookUrl) { + ReadBook.contentLoadFinish( + book, + chapter, + it.msg, + resetPageOffset = resetPageOffset + ) + } + }.onFinally { + downloadMap[book.bookUrl]?.remove(chapter.index) + ReadBook.removeLoading(chapter.index) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index 479850620..3d412a70b 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -1,10 +1,8 @@ package io.legado.app.service.help -import android.util.Log import androidx.lifecycle.MutableLiveData import com.hankcs.hanlp.HanLP import io.legado.app.App -import io.legado.app.R import io.legado.app.constant.BookType import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter @@ -61,6 +59,9 @@ object ReadBook { titleDate.postValue(book.name) upWebBook(book) ImageProvider.clearAllCache() + synchronized(this) { + loadingChapters.clear() + } } fun upWebBook(book: Book) { @@ -270,35 +271,7 @@ object ReadBook { val book = book val webBook = webBook if (book != null && webBook != null) { - webBook.getContent(book, chapter) - .onSuccess(Dispatchers.IO) { content -> - if (content.isEmpty()) { - contentLoadFinish( - book, - chapter, - App.INSTANCE.getString(R.string.content_empty), - resetPageOffset = resetPageOffset - ) - removeLoading(chapter.index) - } else { - BookHelp.saveContent(book, chapter, content) - contentLoadFinish( - book, - chapter, - content, - resetPageOffset = resetPageOffset - ) - removeLoading(chapter.index) - } - }.onError { - contentLoadFinish( - book, - chapter, - it.localizedMessage ?: "未知错误", - resetPageOffset = resetPageOffset - ) - removeLoading(chapter.index) - } + CacheBook.download(webBook, book, chapter) } else if (book != null) { contentLoadFinish( book, @@ -320,31 +293,34 @@ object ReadBook { } } - private fun removeLoading(index: Int) { + fun removeLoading(index: Int) { synchronized(this) { loadingChapters.remove(index) } } - fun searchResultPositions(pages: List, indexWithinChapter: Int, query: String): Array{ - // + fun searchResultPositions( + pages: List, + indexWithinChapter: Int, + query: String + ): Array { // calculate search result's pageIndex var content = "" - pages.map{ - content+= it.text + pages.map { + content += it.text } var count = 1 var index = content.indexOf(query) - while(count != indexWithinChapter){ - index = content.indexOf(query, index + 1); + while (count != indexWithinChapter) { + index = content.indexOf(query, index + 1) count += 1 } val contentPosition = index var pageIndex = 0 var length = pages[pageIndex].text.length - while (length < contentPosition){ + while (length < contentPosition) { pageIndex += 1 - if (pageIndex >pages.size){ + if (pageIndex > pages.size) { pageIndex = pages.size break } @@ -355,9 +331,9 @@ object ReadBook { val currentPage = pages[pageIndex] var lineIndex = 0 length = length - currentPage.text.length + currentPage.textLines[lineIndex].text.length - while (length < contentPosition){ + while (length < contentPosition) { lineIndex += 1 - if (lineIndex >currentPage.textLines.size){ + if (lineIndex > currentPage.textLines.size) { lineIndex = currentPage.textLines.size break } @@ -371,12 +347,12 @@ object ReadBook { var addLine = 0 var charIndex2 = 0 // change line - if ((charIndex + query.length) > currentLine.text.length){ + if ((charIndex + query.length) > currentLine.text.length) { addLine = 1 charIndex2 = charIndex + query.length - currentLine.text.length - 1 } // changePage - if ((lineIndex + addLine + 1) > currentPage.textLines.size){ + if ((lineIndex + addLine + 1) > currentPage.textLines.size) { addLine = -1 charIndex2 = charIndex + query.length - currentLine.text.length - 1 } @@ -386,7 +362,7 @@ object ReadBook { /** * 内容加载完成 */ - private fun contentLoadFinish( + fun contentLoadFinish( book: Book, chapter: BookChapter, content: String, diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index c9fc9066a..9a10d0060 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -12,6 +12,7 @@ import io.legado.app.help.DefaultValueHelp import io.legado.app.help.http.HttpHelper import io.legado.app.help.storage.Restore import io.legado.app.model.webBook.WebBook +import io.legado.app.service.help.CacheBook import io.legado.app.utils.FileUtils import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject @@ -21,6 +22,7 @@ import kotlinx.coroutines.asCoroutineDispatcher import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.Executors +import kotlin.math.min class MainViewModel(application: Application) : BaseViewModel(application) { private var threadCount = AppConfig.threadCount @@ -74,12 +76,14 @@ class MainViewModel(application: Application) : BaseViewModel(application) { postEvent(EventBus.UP_BOOK, book.bookUrl) } App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource -> - WebBook(bookSource).getChapterList(book, context = upTocPool) + val webBook = WebBook(bookSource) + webBook.getChapterList(book, context = upTocPool) .timeout(300000) .onSuccess(IO) { App.db.bookDao().update(book) App.db.bookChapterDao().delByBook(book.bookUrl) App.db.bookChapterDao().insert(*it.toTypedArray()) + cacheBook(webBook, book) } .onError { it.printStackTrace() @@ -104,6 +108,17 @@ class MainViewModel(application: Application) : BaseViewModel(application) { } } + private fun cacheBook(webBook: WebBook, book: Book) { + if (book.totalChapterNum > book.durChapterIndex) { + val downloadToIndex = min(book.totalChapterNum, book.durChapterIndex.plus(10)) + for (i in book.durChapterIndex until downloadToIndex) { + App.db.bookChapterDao().getChapter(book.bookUrl, i)?.let { chapter -> + CacheBook.download(webBook, book, chapter) + } + } + } + } + private fun upNext() { if (bookMap.size > updateList.size) { updateToc()