Do not recycle bitmap in pager, add back lrucache
TODO: use coil instead
This commit is contained in:
1 parent
54bd6f6ed8
commit
56ba52d7b9
2 files changed
+31
-6
No files matched your search
@@ -1,12 +1,17 @@
|
||||
package eu.kanade.tachiyomi.ui.reader.loader
|
||||
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.collection.LruCache
|
||||
import com.hippo.image.Image
|
||||
import com.hippo.yorozuya.MathUtils
|
||||
import com.hippo.yorozuya.OSUtils
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
abstract class PageLoader {
|
||||
|
||||
private val mImageCache = ImageCache()
|
||||
val mPages by lazy {
|
||||
check(size() > 0)
|
||||
(0 until size()).map { ReaderPage(it) }
|
||||
@@ -20,14 +25,15 @@ abstract class PageLoader {
|
||||
|
||||
@CallSuper
|
||||
open fun stop() {
|
||||
mPages.forEach { it.image?.recycle() }
|
||||
mImageCache.evictAll()
|
||||
}
|
||||
|
||||
abstract fun size(): Int
|
||||
|
||||
fun request(index: Int) {
|
||||
if (mPages[index].image?.isRecycled == false)
|
||||
notifyPageSucceed(index, mPages[index].image!!)
|
||||
val image = mImageCache[index]
|
||||
if (image != null)
|
||||
notifyPageSucceed(index, image)
|
||||
else
|
||||
onRequest(index)
|
||||
}
|
||||
@@ -63,16 +69,35 @@ abstract class PageLoader {
|
||||
}
|
||||
|
||||
fun notifyPageSucceed(index: Int, image: Image) {
|
||||
val priv = if (image != mPages[index].image) mPages[index].image else null
|
||||
if (mImageCache[index] != image)
|
||||
mImageCache.add(index, image)
|
||||
mPages[index].image = image
|
||||
mPages[index].status.value = Page.State.READY
|
||||
priv?.recycle()
|
||||
}
|
||||
|
||||
fun notifyPageFailed(index: Int) {
|
||||
mPages[index].status.value = Page.State.ERROR
|
||||
}
|
||||
|
||||
private class ImageCache : LruCache<Int, Image>(MathUtils.clamp(OSUtils.getTotalMemory() / 16, MIN_CACHE_SIZE, MAX_CACHE_SIZE).toInt()) {
|
||||
fun add(key: Int, value: Image) {
|
||||
put(key, value)
|
||||
}
|
||||
|
||||
override fun sizeOf(key: Int, value: Image): Int {
|
||||
return value.height * value.width * 4
|
||||
}
|
||||
|
||||
override fun entryRemoved(evicted: Boolean, key: Int, oldValue: Image, newValue: Image?) {
|
||||
oldValue.recycle()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MAX_CACHE_SIZE = (512 * 1024 * 1024).toLong()
|
||||
private const val MIN_CACHE_SIZE = (128 * 1024 * 1024).toLong()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val STATE_WAIT = -1
|
||||
const val STATE_ERROR = -2
|
||||
|
||||
@@ -278,7 +278,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
||||
when (image) {
|
||||
is Drawable -> {
|
||||
val bitmap = (image as BitmapDrawable).bitmap
|
||||
setImage(ImageSource.bitmap(bitmap))
|
||||
setImage(ImageSource.cachedBitmap(bitmap))
|
||||
}
|
||||
is InputStream -> setImage(ImageSource.inputStream(image))
|
||||
else -> throw IllegalArgumentException("Not implemented for class ${image::class.simpleName}")
|
||||
|
||||
Reference in new issue
Block a user