821938089 4 years ago
parent
commit
7950a8d747

+ 1 - 0
app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt

@@ -147,6 +147,7 @@ class Coroutine<T>(
             } catch (e: Throwable) {
                 e.printOnDebug()
                 if (e is CancellationException && e !is TimeoutCancellationException) {
+                    this@Coroutine.cancel()
                     return@launch
                 }
                 val consume: Boolean = errorReturn?.value?.let { value ->

+ 26 - 4
app/src/main/java/io/legado/app/model/CacheBook.kt

@@ -135,6 +135,8 @@ object CacheBook {
         private val onDownloadSet = linkedSetOf<Int>()
         private val successDownloadSet = linkedSetOf<Int>()
         private val errorDownloadMap = hashMapOf<Int, Int>()
+        private var isStopped = false
+        private var waitingRetry = false
 
         val waitCount get() = waitDownloadSet.size
         val onDownloadCount get() = onDownloadSet.size
@@ -146,13 +148,20 @@ object CacheBook {
             return waitDownloadSet.size > 0 || onDownloadSet.size > 0
         }
 
+        @Synchronized
+        fun isStop(): Boolean {
+            return isStopped || (!isRun() && !waitingRetry)
+        }
+
         @Synchronized
         fun stop() {
             waitDownloadSet.clear()
+            isStopped = true
         }
 
         @Synchronized
         fun addDownload(start: Int, end: Int) {
+            isStopped = false
             for (i in start..end) {
                 if (!onDownloadSet.contains(i)) {
                     waitDownloadSet.add(i)
@@ -168,13 +177,18 @@ object CacheBook {
         }
 
         @Synchronized
-        private fun onError(index: Int, error: Throwable, chapterTitle: String) {
+        private fun onPreError(index: Int, error: Throwable) {
+            waitingRetry = true
             if (error !is ConcurrentException) {
                 errorDownloadMap[index] = (errorDownloadMap[index] ?: 0) + 1
             }
             onDownloadSet.remove(index)
+        }
+
+        @Synchronized
+        private fun onPostError(index: Int, error: Throwable, chapterTitle: String) {
             //重试3次
-            if ((errorDownloadMap[index] ?: 0) < 3) {
+            if ((errorDownloadMap[index] ?: 0) < 3 && !isStopped) {
                 waitDownloadSet.add(index)
             } else {
                 AppLog.put(
@@ -182,12 +196,19 @@ object CacheBook {
                     error
                 )
             }
+            waitingRetry = false
+        }
+
+        @Synchronized
+        private fun onError(index: Int, error: Throwable, chapterTitle: String) {
+            onPreError(index, error)
+            onPostError(index, error, chapterTitle)
         }
 
         @Synchronized
         private fun onCancel(index: Int) {
             onDownloadSet.remove(index)
-            waitDownloadSet.add(index)
+            if (!isStopped) waitDownloadSet.add(index)
         }
 
         @Synchronized
@@ -234,9 +255,10 @@ object CacheBook {
                 onSuccess(chapterIndex)
                 downloadFinish(chapter, content)
             }.onError {
+                onPreError(chapterIndex, it)
                 //出现错误等待一秒后重新加入待下载列表
                 delay(1000)
-                onError(chapterIndex, it, chapter.title)
+                onPostError(chapterIndex, it, chapter.title)
                 downloadFinish(chapter, "获取正文失败\n${it.localizedMessage}")
             }.onCancel {
                 onCancel(chapterIndex)

+ 7 - 0
app/src/main/java/io/legado/app/service/CacheBookService.kt

@@ -74,6 +74,7 @@ class CacheBookService : BaseService() {
     override fun onDestroy() {
         isRun = false
         cachePool.close()
+        CacheBook.cacheBookMap.forEach { it.value.stop() }
         CacheBook.cacheBookMap.clear()
         super.onDestroy()
         postEvent(EventBus.UP_DOWNLOAD, "")
@@ -84,6 +85,7 @@ class CacheBookService : BaseService() {
         execute {
             val cacheBook = CacheBook.getOrCreate(bookUrl) ?: return@execute
             cacheBook.addDownload(start, end)
+            postEvent(EventBus.UP_DOWNLOAD, "")
             upNotification(CacheBook.downloadSummary)
             if (downloadJob == null) {
                 download()
@@ -93,6 +95,11 @@ class CacheBookService : BaseService() {
 
     private fun removeDownload(bookUrl: String?) {
         CacheBook.cacheBookMap[bookUrl]?.stop()
+        postEvent(EventBus.UP_DOWNLOAD, "")
+        if (downloadJob == null && CacheBook.isRun) {
+            download()
+            return
+        }
         if (CacheBook.cacheBookMap.isEmpty()) {
             stopSelf()
         }

+ 1 - 0
app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt

@@ -237,6 +237,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
         observeEvent<BookChapter>(EventBus.SAVE_CONTENT) {
             adapter.cacheChapters[it.bookUrl]?.add(it.url)
         }
+        postEventDelay(EventBus.UP_DOWNLOAD, "", 100)
     }
 
     override fun export(position: Int) {

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt

@@ -67,7 +67,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) :
             ivDownload.setOnClickListener {
                 getItem(holder.layoutPosition)?.let { book ->
                     CacheBook.cacheBookMap[book.bookUrl]?.let {
-                        if (it.isRun()) {
+                        if (!it.isStop()) {
                             CacheBook.remove(context, book.bookUrl)
                         } else {
                             CacheBook.start(context, book, 0, book.totalChapterNum)
@@ -89,7 +89,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) :
         } else {
             iv.visible()
             CacheBook.cacheBookMap[book.bookUrl]?.let {
-                if (it.isRun()) {
+                if (!it.isStop()) {
                     iv.setImageResource(R.drawable.ic_stop_black_24dp)
                 } else {
                     iv.setImageResource(R.drawable.ic_play_24dp)

+ 7 - 6
app/src/main/java/io/legado/app/ui/main/MainViewModel.kt

@@ -186,13 +186,14 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
     private fun cacheBook() {
         cacheBookJob?.cancel()
         cacheBookJob = viewModelScope.launch(upTocPool) {
-            while (isActive) {
-                if (CacheBookService.isRun) {
-                    cacheBookJob?.cancel()
-                    cacheBookJob = null
-                    return@launch
+            launch {
+                while (isActive) {
+                    postEvent(EventBus.UP_DOWNLOAD, "")
+                    delay(1000)
                 }
-                if (!CacheBook.isRun) {
+            }
+            while (isActive) {
+                if (CacheBookService.isRun || !CacheBook.isRun) {
                     cacheBookJob?.cancel()
                     cacheBookJob = null
                     return@launch