Ver código fonte

Avoid hard crash if cached image file was already deleted

Closes #9720
arkon 1 ano atrás
pai
commit
3ea026e311

+ 38 - 29
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerPageHolder.kt

@@ -17,10 +17,12 @@ import kotlinx.coroutines.MainScope
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.supervisorScope
+import logcat.LogPriority
 import tachiyomi.core.util.lang.launchIO
 import tachiyomi.core.util.lang.withIOContext
 import tachiyomi.core.util.lang.withUIContext
 import tachiyomi.core.util.system.ImageUtil
+import tachiyomi.core.util.system.logcat
 import java.io.BufferedInputStream
 import java.io.ByteArrayInputStream
 import java.io.InputStream
@@ -136,40 +138,47 @@ class PagerPageHolder(
 
         val streamFn = page.stream ?: return
 
-        val (bais, isAnimated, background) = withIOContext {
-            streamFn().buffered(16).use { stream ->
-                process(item, stream).use { itemStream ->
-                    val bais = ByteArrayInputStream(itemStream.readBytes())
-                    val isAnimated = ImageUtil.isAnimatedAndSupported(bais)
-                    bais.reset()
-                    val background = if (!isAnimated && viewer.config.automaticBackground) {
-                        ImageUtil.chooseBackground(context, bais)
-                    } else {
-                        null
+        try {
+            val (bais, isAnimated, background) = withIOContext {
+                streamFn().buffered(16).use { stream ->
+                    process(item, stream).use { itemStream ->
+                        val bais = ByteArrayInputStream(itemStream.readBytes())
+                        val isAnimated = ImageUtil.isAnimatedAndSupported(bais)
+                        bais.reset()
+                        val background = if (!isAnimated && viewer.config.automaticBackground) {
+                            ImageUtil.chooseBackground(context, bais)
+                        } else {
+                            null
+                        }
+                        bais.reset()
+                        Triple(bais, isAnimated, background)
                     }
-                    bais.reset()
-                    Triple(bais, isAnimated, background)
                 }
             }
-        }
-        withUIContext {
-            bais.use {
-                setImage(
-                    it,
-                    isAnimated,
-                    Config(
-                        zoomDuration = viewer.config.doubleTapAnimDuration,
-                        minimumScaleType = viewer.config.imageScaleType,
-                        cropBorders = viewer.config.imageCropBorders,
-                        zoomStartPosition = viewer.config.imageZoomType,
-                        landscapeZoom = viewer.config.landscapeZoom,
-                    ),
-                )
-                if (!isAnimated) {
-                    pageBackground = background
+            withUIContext {
+                bais.use {
+                    setImage(
+                        it,
+                        isAnimated,
+                        Config(
+                            zoomDuration = viewer.config.doubleTapAnimDuration,
+                            minimumScaleType = viewer.config.imageScaleType,
+                            cropBorders = viewer.config.imageCropBorders,
+                            zoomStartPosition = viewer.config.imageZoomType,
+                            landscapeZoom = viewer.config.landscapeZoom,
+                        ),
+                    )
+                    if (!isAnimated) {
+                        pageBackground = background
+                    }
                 }
+                removeErrorLayout()
+            }
+        } catch (e: Throwable) {
+            logcat(LogPriority.ERROR, e)
+            withUIContext {
+                setError()
             }
-            removeErrorLayout()
         }
     }
 

+ 30 - 21
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonPageHolder.kt

@@ -23,10 +23,12 @@ import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.supervisorScope
 import kotlinx.coroutines.suspendCancellableCoroutine
+import logcat.LogPriority
 import tachiyomi.core.util.lang.launchIO
 import tachiyomi.core.util.lang.withIOContext
 import tachiyomi.core.util.lang.withUIContext
 import tachiyomi.core.util.system.ImageUtil
+import tachiyomi.core.util.system.logcat
 import java.io.BufferedInputStream
 import java.io.InputStream
 
@@ -184,28 +186,35 @@ class WebtoonPageHolder(
 
         val streamFn = page?.stream ?: return
 
-        val (openStream, isAnimated) = withIOContext {
-            val stream = streamFn().buffered(16)
-            val openStream = process(stream)
+        try {
+            val (openStream, isAnimated) = withIOContext {
+                val stream = streamFn().buffered(16)
+                val openStream = process(stream)
 
-            val isAnimated = ImageUtil.isAnimatedAndSupported(stream)
-            Pair(openStream, isAnimated)
-        }
-        withUIContext {
-            frame.setImage(
-                openStream,
-                isAnimated,
-                ReaderPageImageView.Config(
-                    zoomDuration = viewer.config.doubleTapAnimDuration,
-                    minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH,
-                    cropBorders = viewer.config.imageCropBorders,
-                ),
-            )
-            removeErrorLayout()
-        }
-        // Suspend the coroutine to close the input stream only when the WebtoonPageHolder is recycled
-        suspendCancellableCoroutine<Nothing> { continuation ->
-            continuation.invokeOnCancellation { openStream.close() }
+                val isAnimated = ImageUtil.isAnimatedAndSupported(stream)
+                Pair(openStream, isAnimated)
+            }
+            withUIContext {
+                frame.setImage(
+                    openStream,
+                    isAnimated,
+                    ReaderPageImageView.Config(
+                        zoomDuration = viewer.config.doubleTapAnimDuration,
+                        minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_FIT_WIDTH,
+                        cropBorders = viewer.config.imageCropBorders,
+                    ),
+                )
+                removeErrorLayout()
+            }
+            // Suspend the coroutine to close the input stream only when the WebtoonPageHolder is recycled
+            suspendCancellableCoroutine<Nothing> { continuation ->
+                continuation.invokeOnCancellation { openStream.close() }
+            }
+        } catch (e: Throwable) {
+            logcat(LogPriority.ERROR, e)
+            withUIContext {
+                setError()
+            }
         }
     }