diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index 147d33e41..af6cbed8d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -3,6 +3,7 @@ package io.legado.app.ui.book.read.page.provider import android.graphics.Bitmap import android.graphics.BitmapFactory import android.util.Size +import androidx.collection.LruCache import io.legado.app.R import io.legado.app.constant.AppLog.putDebug import io.legado.app.data.entities.Book @@ -23,6 +24,33 @@ object ImageProvider { BitmapFactory.decodeResource(appCtx.resources, R.drawable.image_loading_error) } + /** + *缓存bitmap LruCache实现 + */ + //private val maxMemory = Runtime.getRuntime().maxMemory() + //private val cacheMemorySize = (maxMemory / 8) as Int + private val cacheMemorySize: Int = 1024 * 1024 * 1024 //1G + private val bitmapLruCache = object : LruCache(cacheMemorySize) { + override fun sizeOf(key: String, bitmap: Bitmap): Int { + return bitmap.getByteCount() + } + override fun entryRemoved( + evicted: Boolean, + key: String, + oldBitmap: Bitmap, + newBitmap: Bitmap? + ) { + if (evicted) { + oldBitmap.recycle() + putDebug("自动回收Bitmap path: $key") + putDebug("bitmapLruCache : ${size()} / ${maxSize()}") + } + } + } + + /** + *缓存网络图片和epub图片 + */ suspend fun cacheImage( book: Book, src: String, @@ -45,6 +73,9 @@ object ImageProvider { return vFile } + /** + *获取图片宽度高度信息 + */ suspend fun getImageSize( book: Book, src: String, @@ -58,16 +89,23 @@ object ImageProvider { return Size(op.outWidth, op.outHeight) } + /** + *获取bitmap 使用LruCache缓存 + */ fun getImage( book: Book, src: String, width: Int, height: Int ): Bitmap { + val cacheBitmap = bitmapLruCache.get(src) + if (cacheBitmap != null) return cacheBitmap val vFile = BookHelp.getImage(book, src) @Suppress("BlockingMethodInNonBlockingContext") return try { - BitmapUtils.decodeBitmap(vFile.absolutePath, width, height) + val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height) + bitmapLruCache.put(src, bitmap) + bitmap } catch (e: Exception) { Coroutine.async { putDebug("${vFile.absolutePath} 解码失败\n$e", e) @@ -80,15 +118,22 @@ object ImageProvider { } } + /** + *获取bitmap 使用LruCache缓存 + */ fun getImage( book: Book, src: String, width: Int ): Bitmap { + val cacheBitmap = bitmapLruCache.get(src) + if (cacheBitmap != null) return cacheBitmap val vFile = BookHelp.getImage(book, src) @Suppress("BlockingMethodInNonBlockingContext") return try { - BitmapUtils.decodeBitmap(vFile.absolutePath, width) + val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width) + bitmapLruCache.put(src, bitmap) + bitmap } catch (e: Exception) { Coroutine.async { putDebug("${vFile.absolutePath} 解码失败\n$e", e)