更新目录时预下载章节内容

pull/416/head
gedoor 4 years ago
parent 3f769950c5
commit d357954635
  1. 60
      app/src/main/java/io/legado/app/service/help/CacheBook.kt
  2. 66
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  3. 17
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt

@ -2,12 +2,22 @@ package io.legado.app.service.help
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import io.legado.app.App
import io.legado.app.R
import io.legado.app.constant.IntentAction 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.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 { object CacheBook {
val logs = arrayListOf<String>() val logs = arrayListOf<String>()
private val downloadMap = ConcurrentHashMap<String, CopyOnWriteArraySet<Int>>()
fun addLog(log: String?) { fun addLog(log: String?) {
log ?: return 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)
}
}
} }

@ -1,10 +1,8 @@
package io.legado.app.service.help package io.legado.app.service.help
import android.util.Log
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.hankcs.hanlp.HanLP import com.hankcs.hanlp.HanLP
import io.legado.app.App import io.legado.app.App
import io.legado.app.R
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
@ -61,6 +59,9 @@ object ReadBook {
titleDate.postValue(book.name) titleDate.postValue(book.name)
upWebBook(book) upWebBook(book)
ImageProvider.clearAllCache() ImageProvider.clearAllCache()
synchronized(this) {
loadingChapters.clear()
}
} }
fun upWebBook(book: Book) { fun upWebBook(book: Book) {
@ -270,35 +271,7 @@ object ReadBook {
val book = book val book = book
val webBook = webBook val webBook = webBook
if (book != null && webBook != null) { if (book != null && webBook != null) {
webBook.getContent(book, chapter) CacheBook.download(webBook, 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)
}
} else if (book != null) { } else if (book != null) {
contentLoadFinish( contentLoadFinish(
book, book,
@ -320,31 +293,34 @@ object ReadBook {
} }
} }
private fun removeLoading(index: Int) { fun removeLoading(index: Int) {
synchronized(this) { synchronized(this) {
loadingChapters.remove(index) loadingChapters.remove(index)
} }
} }
fun searchResultPositions(pages: List<TextPage>, indexWithinChapter: Int, query: String): Array<Int>{ fun searchResultPositions(
// pages: List<TextPage>,
indexWithinChapter: Int,
query: String
): Array<Int> {
// calculate search result's pageIndex // calculate search result's pageIndex
var content = "" var content = ""
pages.map{ pages.map {
content+= it.text content += it.text
} }
var count = 1 var count = 1
var index = content.indexOf(query) var index = content.indexOf(query)
while(count != indexWithinChapter){ while (count != indexWithinChapter) {
index = content.indexOf(query, index + 1); index = content.indexOf(query, index + 1)
count += 1 count += 1
} }
val contentPosition = index val contentPosition = index
var pageIndex = 0 var pageIndex = 0
var length = pages[pageIndex].text.length var length = pages[pageIndex].text.length
while (length < contentPosition){ while (length < contentPosition) {
pageIndex += 1 pageIndex += 1
if (pageIndex >pages.size){ if (pageIndex > pages.size) {
pageIndex = pages.size pageIndex = pages.size
break break
} }
@ -355,9 +331,9 @@ object ReadBook {
val currentPage = pages[pageIndex] val currentPage = pages[pageIndex]
var lineIndex = 0 var lineIndex = 0
length = length - currentPage.text.length + currentPage.textLines[lineIndex].text.length length = length - currentPage.text.length + currentPage.textLines[lineIndex].text.length
while (length < contentPosition){ while (length < contentPosition) {
lineIndex += 1 lineIndex += 1
if (lineIndex >currentPage.textLines.size){ if (lineIndex > currentPage.textLines.size) {
lineIndex = currentPage.textLines.size lineIndex = currentPage.textLines.size
break break
} }
@ -371,12 +347,12 @@ object ReadBook {
var addLine = 0 var addLine = 0
var charIndex2 = 0 var charIndex2 = 0
// change line // change line
if ((charIndex + query.length) > currentLine.text.length){ if ((charIndex + query.length) > currentLine.text.length) {
addLine = 1 addLine = 1
charIndex2 = charIndex + query.length - currentLine.text.length - 1 charIndex2 = charIndex + query.length - currentLine.text.length - 1
} }
// changePage // changePage
if ((lineIndex + addLine + 1) > currentPage.textLines.size){ if ((lineIndex + addLine + 1) > currentPage.textLines.size) {
addLine = -1 addLine = -1
charIndex2 = charIndex + query.length - currentLine.text.length - 1 charIndex2 = charIndex + query.length - currentLine.text.length - 1
} }
@ -386,7 +362,7 @@ object ReadBook {
/** /**
* 内容加载完成 * 内容加载完成
*/ */
private fun contentLoadFinish( fun contentLoadFinish(
book: Book, book: Book,
chapter: BookChapter, chapter: BookChapter,
content: String, content: String,

@ -12,6 +12,7 @@ import io.legado.app.help.DefaultValueHelp
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Restore import io.legado.app.help.storage.Restore
import io.legado.app.model.webBook.WebBook 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.FileUtils
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
@ -21,6 +22,7 @@ import kotlinx.coroutines.asCoroutineDispatcher
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.CopyOnWriteArraySet
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.min
class MainViewModel(application: Application) : BaseViewModel(application) { class MainViewModel(application: Application) : BaseViewModel(application) {
private var threadCount = AppConfig.threadCount private var threadCount = AppConfig.threadCount
@ -74,12 +76,14 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
postEvent(EventBus.UP_BOOK, book.bookUrl) postEvent(EventBus.UP_BOOK, book.bookUrl)
} }
App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource -> 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) .timeout(300000)
.onSuccess(IO) { .onSuccess(IO) {
App.db.bookDao().update(book) App.db.bookDao().update(book)
App.db.bookChapterDao().delByBook(book.bookUrl) App.db.bookChapterDao().delByBook(book.bookUrl)
App.db.bookChapterDao().insert(*it.toTypedArray()) App.db.bookChapterDao().insert(*it.toTypedArray())
cacheBook(webBook, book)
} }
.onError { .onError {
it.printStackTrace() 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() { private fun upNext() {
if (bookMap.size > updateList.size) { if (bookMap.size > updateList.size) {
updateToc() updateToc()

Loading…
Cancel
Save