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 2de647b38..6613bce69 100644 --- a/app/src/main/java/io/legado/app/model/CacheBook.kt +++ b/app/src/main/java/io/legado/app/model/CacheBook.kt @@ -2,6 +2,7 @@ package io.legado.app.model import android.annotation.SuppressLint import android.content.Context +import io.legado.app.constant.EventBus import io.legado.app.constant.IntentAction import io.legado.app.data.appDb import io.legado.app.data.entities.Book @@ -10,10 +11,12 @@ import io.legado.app.data.entities.BookSource import io.legado.app.help.BookHelp import io.legado.app.model.webBook.WebBook import io.legado.app.service.CacheBookService +import io.legado.app.utils.postEvent import io.legado.app.utils.startService import kotlinx.coroutines.CoroutineScope import java.text.SimpleDateFormat import java.util.* +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.CopyOnWriteArraySet import kotlin.coroutines.CoroutineContext @@ -22,7 +25,7 @@ class CacheBook(val bookSource: BookSource, val book: Book) { companion object { val logs = arrayListOf() - val cacheBookMap = hashMapOf() + val cacheBookMap = ConcurrentHashMap() @SuppressLint("ConstantLocale") private val logTimeFormat = SimpleDateFormat("[mm:ss.SSS]", Locale.getDefault()) @@ -83,6 +86,8 @@ class CacheBook(val bookSource: BookSource, val book: Book) { } } + val isRun: Boolean get() = waitDownloadCount > 0 || onDownloadCount > 0 + val waitDownloadCount: Int get() { var count = 0 @@ -113,8 +118,8 @@ class CacheBook(val bookSource: BookSource, val book: Book) { } val waitDownloadSet = CopyOnWriteArraySet() - val successDownloadSet = CopyOnWriteArraySet() val onDownloadSet = CopyOnWriteArraySet() + val successDownloadSet = CopyOnWriteArraySet() fun addDownload(start: Int, end: Int) { for (i in start..end) { @@ -122,6 +127,10 @@ class CacheBook(val bookSource: BookSource, val book: Book) { } } + fun isRun(): Boolean { + return waitDownloadSet.size > 0 || onDownloadSet.size > 0 + } + @Synchronized fun download(scope: CoroutineScope, context: CoroutineContext): Boolean { val chapterIndex = waitDownloadSet.firstOrNull() ?: return false @@ -158,6 +167,10 @@ class CacheBook(val bookSource: BookSource, val book: Book) { }.onCancel { onDownloadSet.remove(chapterIndex) waitDownloadSet.add(chapterIndex) + }.onFinally { + if (waitDownloadSet.isEmpty() && onDownloadSet.isEmpty()) { + postEvent(EventBus.UP_DOWNLOAD, "") + } } return true } diff --git a/app/src/main/java/io/legado/app/service/CacheBookService.kt b/app/src/main/java/io/legado/app/service/CacheBookService.kt index 1317df827..9830b865a 100644 --- a/app/src/main/java/io/legado/app/service/CacheBookService.kt +++ b/app/src/main/java/io/legado/app/service/CacheBookService.kt @@ -66,6 +66,7 @@ class CacheBookService : BaseService() { override fun onDestroy() { cachePool.close() + CacheBook.cacheBookMap.clear() super.onDestroy() postEvent(EventBus.UP_DOWNLOAD, "") } diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index 503908fff..9c0a2e4c3 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -35,8 +35,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.CopyOnWriteArraySet class CacheActivity : VMBaseActivity(), CacheAdapter.CallBack { @@ -113,7 +111,7 @@ class CacheActivity : VMBaseActivity() override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_download -> { - if (adapter.downloadMap.isNullOrEmpty()) { + if (!CacheBook.isRun) { adapter.getItems().forEach { book -> CacheBook.start( this@CacheActivity, @@ -212,15 +210,14 @@ class CacheActivity : VMBaseActivity() } override fun observeLiveBus() { - observeEvent>>(EventBus.UP_DOWNLOAD) { - if (it.isEmpty()) { + observeEvent(EventBus.UP_DOWNLOAD) { + if (!CacheBook.isRun) { menu?.findItem(R.id.menu_download)?.setIcon(R.drawable.ic_play_24dp) menu?.applyTint(this) } else { menu?.findItem(R.id.menu_download)?.setIcon(R.drawable.ic_stop_black_24dp) menu?.applyTint(this) } - adapter.downloadMap = it adapter.notifyItemRangeChanged(0, adapter.itemCount, true) } observeEvent(EventBus.SAVE_CONTENT) { diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt index 923893100..998d33202 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt @@ -7,19 +7,13 @@ import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.data.entities.Book -import io.legado.app.data.entities.BookChapter import io.legado.app.databinding.ItemDownloadBinding import io.legado.app.model.CacheBook -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.CopyOnWriteArraySet - - class CacheAdapter(context: Context, private val callBack: CallBack) : RecyclerAdapter(context) { val cacheChapters = hashMapOf>() - var downloadMap: ConcurrentHashMap>? = null override fun getViewBinding(parent: ViewGroup): ItemDownloadBinding { return ItemDownloadBinding.inflate(inflater, parent, false) @@ -55,11 +49,15 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : override fun registerListener(holder: ItemViewHolder, binding: ItemDownloadBinding) { binding.run { ivDownload.setOnClickListener { - getItem(holder.layoutPosition)?.let { - if (downloadMap?.containsKey(it.bookUrl) == true) { - CacheBook.remove(context, it.bookUrl) - } else { - CacheBook.start(context, it.bookUrl, 0, it.totalChapterNum) + getItem(holder.layoutPosition)?.let { book -> + CacheBook.get(book.bookUrl)?.let { + if (it.isRun()) { + CacheBook.remove(context, book.bookUrl) + } else { + CacheBook.start(context, book.bookUrl, 0, book.totalChapterNum) + } + } ?: let { + CacheBook.start(context, book.bookUrl, 0, book.totalChapterNum) } } } @@ -70,8 +68,8 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : } private fun upDownloadIv(iv: ImageView, book: Book) { - downloadMap?.let { - if (it.containsKey(book.bookUrl)) { + CacheBook.get(book.bookUrl)?.let { + if (it.isRun()) { iv.setImageResource(R.drawable.ic_stop_black_24dp) } else { iv.setImageResource(R.drawable.ic_play_24dp)