优化
This commit is contained in:
@@ -34,6 +34,8 @@ object BookHelp {
|
|||||||
private const val cacheEpubFolderName = "epub"
|
private const val cacheEpubFolderName = "epub"
|
||||||
private val downloadImages = CopyOnWriteArraySet<String>()
|
private val downloadImages = CopyOnWriteArraySet<String>()
|
||||||
|
|
||||||
|
val cachePath = FileUtils.getPath(downloadDir, cacheFolderName)
|
||||||
|
|
||||||
fun clearCache() {
|
fun clearCache() {
|
||||||
FileUtils.delete(
|
FileUtils.delete(
|
||||||
FileUtils.getPath(downloadDir, cacheFolderName)
|
FileUtils.getPath(downloadDir, cacheFolderName)
|
||||||
@@ -196,18 +198,18 @@ object BookHelp {
|
|||||||
return ZipFile(uri.path)
|
return ZipFile(uri.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getChapterFiles(book: Book): List<String> {
|
fun getChapterFiles(book: Book): Set<String> {
|
||||||
val fileNameList = arrayListOf<String>()
|
|
||||||
if (book.isLocalTxt) {
|
if (book.isLocalTxt) {
|
||||||
return fileNameList
|
return emptySet()
|
||||||
}
|
}
|
||||||
|
val fileNames = hashSetOf<String>()
|
||||||
FileUtils.createFolderIfNotExist(
|
FileUtils.createFolderIfNotExist(
|
||||||
downloadDir,
|
downloadDir,
|
||||||
subDirs = arrayOf(cacheFolderName, book.getFolderName())
|
subDirs = arrayOf(cacheFolderName, book.getFolderName())
|
||||||
).list()?.let {
|
).list()?.let {
|
||||||
fileNameList.addAll(it)
|
fileNames.addAll(it)
|
||||||
}
|
}
|
||||||
return fileNameList
|
return fileNames
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import io.legado.app.ui.about.AppLogDialog
|
|||||||
import io.legado.app.ui.document.HandleFileContract
|
import io.legado.app.ui.document.HandleFileContract
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
@@ -72,7 +71,6 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
|
|||||||
initRecyclerView()
|
initRecyclerView()
|
||||||
initGroupData()
|
initGroupData()
|
||||||
initBookData()
|
initBookData()
|
||||||
initCacheData()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
@@ -191,17 +189,6 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initCacheData() {
|
|
||||||
launch {
|
|
||||||
viewModel.bookCacheFlow.conflate().collect {
|
|
||||||
viewModel.cacheChapters[it.first] = it.second
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
adapter.notifyItemRangeChanged(0, adapter.itemCount, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun observeLiveBus() {
|
override fun observeLiveBus() {
|
||||||
viewModel.upAdapterLiveData.observe(this) {
|
viewModel.upAdapterLiveData.observe(this) {
|
||||||
adapter.getItems().forEachIndexed { index, book ->
|
adapter.getItems().forEachIndexed { index, book ->
|
||||||
@@ -232,6 +219,11 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
|
|||||||
}
|
}
|
||||||
observeEvent<BookChapter>(EventBus.SAVE_CONTENT) {
|
observeEvent<BookChapter>(EventBus.SAVE_CONTENT) {
|
||||||
viewModel.cacheChapters[it.bookUrl]?.add(it.url)
|
viewModel.cacheChapters[it.bookUrl]?.add(it.url)
|
||||||
|
adapter.getItems().forEachIndexed { index, book ->
|
||||||
|
if (book.bookUrl == it.bookUrl) {
|
||||||
|
adapter.notifyItemChanged(index, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+60
-19
@@ -25,14 +25,12 @@ import io.legado.app.help.book.ContentProcessor
|
|||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.help.coroutine.OrderCoroutine
|
import io.legado.app.help.coroutine.OrderCoroutine
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.flow.flowOn
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import me.ag2s.epublib.domain.*
|
import me.ag2s.epublib.domain.*
|
||||||
|
import me.ag2s.epublib.domain.Date
|
||||||
import me.ag2s.epublib.epub.EpubWriter
|
import me.ag2s.epublib.epub.EpubWriter
|
||||||
import me.ag2s.epublib.util.ResourceUtil
|
import me.ag2s.epublib.util.ResourceUtil
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
@@ -40,6 +38,8 @@ import java.io.ByteArrayOutputStream
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
import java.nio.file.*
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
@@ -49,27 +49,68 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
|
|||||||
val exportProgress = ConcurrentHashMap<String, Int>()
|
val exportProgress = ConcurrentHashMap<String, Int>()
|
||||||
val exportMsg = ConcurrentHashMap<String, String>()
|
val exportMsg = ConcurrentHashMap<String, String>()
|
||||||
private val mutex = Mutex()
|
private val mutex = Mutex()
|
||||||
|
|
||||||
val cacheChapters = hashMapOf<String, HashSet<String>>()
|
val cacheChapters = hashMapOf<String, HashSet<String>>()
|
||||||
|
|
||||||
val bookCacheFlow = flow {
|
|
||||||
//直接获取全部缓存信息,避免切换分组重新获取
|
|
||||||
val books = appDb.bookDao.getByTypeOnLine(BookType.text or BookType.image)
|
|
||||||
books.forEach { book ->
|
|
||||||
val chapterCaches = hashSetOf<String>()
|
|
||||||
val cacheNames = BookHelp.getChapterFiles(book)
|
|
||||||
appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
|
|
||||||
if (cacheNames.contains(chapter.getFileName())) {
|
|
||||||
chapterCaches.add(chapter.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit(Pair(book.bookUrl, chapterCaches))
|
|
||||||
}
|
|
||||||
}.flowOn(Dispatchers.IO)
|
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var exportNumber = 0
|
private var exportNumber = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
loadCacheFiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadCacheFiles() {
|
||||||
|
execute {
|
||||||
|
//直接获取全部缓存信息,避免切换分组重新获取
|
||||||
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// val visitor = object : SimpleFileVisitor<Path>() {
|
||||||
|
//
|
||||||
|
// var names: HashSet<String>? = null
|
||||||
|
//
|
||||||
|
// override fun preVisitDirectory(
|
||||||
|
// dir: Path,
|
||||||
|
// attrs: BasicFileAttributes?
|
||||||
|
// ): FileVisitResult {
|
||||||
|
// if (dir.name != "book_cache") {
|
||||||
|
// names = hashSetOf()
|
||||||
|
// }
|
||||||
|
// return FileVisitResult.CONTINUE
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun visitFile(
|
||||||
|
// file: Path,
|
||||||
|
// attrs: BasicFileAttributes?
|
||||||
|
// ): FileVisitResult {
|
||||||
|
// names!!.add(file.name)
|
||||||
|
// return FileVisitResult.CONTINUE
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
|
||||||
|
// if (dir.name != "book_cache") {
|
||||||
|
// cacheChapters[dir.name] = names!!
|
||||||
|
// }
|
||||||
|
// return FileVisitResult.CONTINUE
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// withContext(Dispatchers.IO) {
|
||||||
|
// Files.walkFileTree(Paths.get(BookHelp.cachePath), emptySet(), 2, visitor)
|
||||||
|
// }
|
||||||
|
// return@execute
|
||||||
|
// }
|
||||||
|
val books = appDb.bookDao.getByTypeOnLine(BookType.text or BookType.image)
|
||||||
|
books.forEach { book ->
|
||||||
|
val chapterCaches = hashSetOf<String>()
|
||||||
|
val cacheNames = BookHelp.getChapterFiles(book)
|
||||||
|
appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
|
||||||
|
if (cacheNames.contains(chapter.getFileName())) {
|
||||||
|
chapterCaches.add(chapter.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cacheChapters[book.bookUrl] = chapterCaches
|
||||||
|
upAdapterLiveData.postValue(book.bookUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getExportFileName(book: Book): String {
|
private fun getExportFileName(book: Book): String {
|
||||||
val jsStr = AppConfig.bookExportFileName
|
val jsStr = AppConfig.bookExportFileName
|
||||||
if (jsStr.isNullOrBlank()) {
|
if (jsStr.isNullOrBlank()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user