Don't recycle visible images
This commit is contained in:
1 parent
a08b8e96e5
commit
5a46fc4573
3 files changed
+27
-13
No files matched your search
@@ -18,7 +18,6 @@
|
||||
package com.hippo.ehviewer.image
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Animatable
|
||||
import androidx.compose.ui.unit.IntRect
|
||||
import arrow.core.Either
|
||||
import arrow.core.left
|
||||
@@ -51,7 +50,7 @@ import java.nio.ByteBuffer
|
||||
import okio.Path
|
||||
import splitties.init.appCtx
|
||||
|
||||
class Image private constructor(image: CoilImage, private val src: AutoCloseable) {
|
||||
class Image private constructor(image: CoilImage, private val src: ImageSource) {
|
||||
val size = image.size
|
||||
val rect = when (image) {
|
||||
is BitmapImageWithRect -> image.rect
|
||||
@@ -63,14 +62,12 @@ class Image private constructor(image: CoilImage, private val src: AutoCloseable
|
||||
else -> image
|
||||
}
|
||||
|
||||
var isRecyclable = true
|
||||
|
||||
@Synchronized
|
||||
fun recycle() {
|
||||
when (val image = innerImage ?: return) {
|
||||
is DrawableImage -> {
|
||||
(image.drawable as Animatable).stop()
|
||||
image.drawable.callback = null
|
||||
src.close()
|
||||
}
|
||||
is DrawableImage -> src.close()
|
||||
is BitmapImage -> image.bitmap.recycle()
|
||||
}
|
||||
innerImage = null
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -66,6 +67,17 @@ fun PagerItem(
|
||||
val painter = remember(image) { image.toPainter() }
|
||||
val grayScale by Settings.grayScale.collectAsState()
|
||||
val invert by Settings.invertedColors.collectAsState()
|
||||
DisposableEffect(image) {
|
||||
image.isRecyclable = false
|
||||
onDispose {
|
||||
if (image.isRecyclable) {
|
||||
pageLoader.notifyPageWait(page.index)
|
||||
image.recycle()
|
||||
} else {
|
||||
image.isRecyclable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
Image(
|
||||
painter = painter,
|
||||
contentDescription = null,
|
||||
|
||||
@@ -23,8 +23,12 @@ abstract class PageLoader {
|
||||
},
|
||||
sizeOf = { _, v -> v.size.toInt() },
|
||||
onEntryRemoved = { _, k, o, n ->
|
||||
n ?: notifyPageWait(k)
|
||||
o.recycle()
|
||||
if (o.isRecyclable) {
|
||||
n ?: notifyPageWait(k)
|
||||
o.recycle()
|
||||
} else {
|
||||
o.isRecyclable = true
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -63,7 +67,7 @@ abstract class PageLoader {
|
||||
fun request(index: Int) {
|
||||
val image = cache[index]
|
||||
if (image != null) {
|
||||
notifyPageSucceed(index, image)
|
||||
notifyPageSucceed(index, image, false)
|
||||
} else {
|
||||
notifyPageWait(index)
|
||||
onRequest(index)
|
||||
@@ -107,16 +111,17 @@ abstract class PageLoader {
|
||||
protected abstract fun onCancelRequest(index: Int)
|
||||
|
||||
fun notifyPageWait(index: Int) {
|
||||
pages[index].progress = 0
|
||||
pages[index].status.value = Page.State.QUEUE
|
||||
}
|
||||
|
||||
fun notifyPagePercent(index: Int, percent: Float) {
|
||||
pages[index].status.compareAndSet(Page.State.QUEUE, Page.State.DOWNLOAD_IMAGE)
|
||||
pages[index].progress = (percent * 100).toInt()
|
||||
pages[index].status.compareAndSet(Page.State.QUEUE, Page.State.DOWNLOAD_IMAGE)
|
||||
}
|
||||
|
||||
fun notifyPageSucceed(index: Int, image: Image) {
|
||||
if (cache[index] != image) {
|
||||
fun notifyPageSucceed(index: Int, image: Image, replaceCache: Boolean = true) {
|
||||
if (replaceCache) {
|
||||
cache.put(index, image)
|
||||
}
|
||||
pages[index].image = image
|
||||
|
||||
Reference in new issue
Block a user