Quellcode durchsuchen

Fix app freezes when queueing many chapters with SAF. Closes #817

len vor 7 Jahren
Ursprung
Commit
5c662b1ae1
1 geänderte Dateien mit 43 neuen und 49 gelöschten Zeilen
  1. 43 49
      app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt

+ 43 - 49
app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt

@@ -91,7 +91,6 @@ class Downloader(private val context: Context, private val provider: DownloadPro
 
     init {
         Observable.fromCallable { store.restore() }
-                .map { downloads -> downloads.filter { isDownloadAllowed(it) } }
                 .subscribeOn(Schedulers.io())
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe({ downloads -> queue.addAll(downloads)
@@ -213,8 +212,7 @@ class Downloader(private val context: Context, private val provider: DownloadPro
     }
 
     /**
-     * Creates a download object for every chapter and adds them to the downloads queue. This method
-     * must be called in the main thread.
+     * Creates a download object for every chapter and adds them to the downloads queue.
      *
      * @param manga the manga of the chapters to download.
      * @param chapters the list of chapters to download.
@@ -222,52 +220,48 @@ class Downloader(private val context: Context, private val provider: DownloadPro
     fun queueChapters(manga: Manga, chapters: List<Chapter>) {
         val source = sourceManager.get(manga.source) as? HttpSource ?: return
 
-        val chaptersToQueue = chapters
-                // Avoid downloading chapters with the same name.
-                .distinctBy { it.name }
-                // Add chapters to queue from the start.
-                .sortedByDescending { it.source_order }
-                // Create a downloader for each one.
-                .map { Download(source, manga, it) }
-                // Filter out those already queued or downloaded.
-                .filter { isDownloadAllowed(it) }
-
-        // Return if there's nothing to queue.
-        if (chaptersToQueue.isEmpty())
-            return
-
-        queue.addAll(chaptersToQueue)
-
-        // Initialize queue size.
-        notifier.initialQueueSize = queue.size
-
-        // Initial multi-thread
-        notifier.multipleDownloadThreads = preferences.downloadThreads().getOrDefault() > 1
-
-        if (isRunning) {
-            // Send the list of downloads to the downloader.
-            downloadsRelay.call(chaptersToQueue)
-        } else {
-            // Show initial notification.
-            notifier.onProgressChange(queue)
-        }
-    }
-
-    /**
-     * Returns true if the given download can be queued and downloaded.
-     *
-     * @param download the download to be checked.
-     */
-    private fun isDownloadAllowed(download: Download): Boolean {
-        // If the chapter is already queued, don't add it again
-        if (queue.any { it.chapter.id == download.chapter.id })
-            return false
-
-        val dir = provider.findChapterDir(download.source, download.manga, download.chapter)
-        if (dir != null && dir.exists())
-            return false
-
-        return true
+        Observable
+                // Background, long running checks
+                .fromCallable {
+                    val mangaDir = provider.findMangaDir(source, manga)
+
+                    chapters
+                            // Avoid downloading chapters with the same name.
+                            .distinctBy { it.name }
+                            // Filter out those already downloaded.
+                            .filter { mangaDir?.findFile(provider.getChapterDirName(it)) == null }
+                            // Add chapters to queue from the start.
+                            .sortedByDescending { it.source_order }
+                }
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                // Main thread, quick checks
+                .map { chaptersToQueue ->
+                    chaptersToQueue
+                            // Filter out those already enqueued.
+                            .filter { chapter -> queue.none { it.chapter.id == chapter.id } }
+                            // Create a download for each one.
+                            .map { Download(source, manga, it) }
+                }
+                .subscribe { chaptersToQueue ->
+                    if (chaptersToQueue.isNotEmpty()) {
+                        queue.addAll(chaptersToQueue)
+
+                        // Initialize queue size.
+                        notifier.initialQueueSize = queue.size
+
+                        // Initial multi-thread
+                        notifier.multipleDownloadThreads = preferences.downloadThreads().getOrDefault() > 1
+
+                        if (isRunning) {
+                            // Send the list of downloads to the downloader.
+                            downloadsRelay.call(chaptersToQueue)
+                        } else {
+                            // Show initial notification.
+                            notifier.onProgressChange(queue)
+                        }
+                    }
+                }
     }
 
     /**