feat:add LruCache
https://developer.android.google.cn/reference/kotlin/androidx/collection/LruCache
This commit is contained in:
@@ -3,6 +3,7 @@ package io.legado.app.ui.book.read.page.provider
|
|||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.util.Size
|
import android.util.Size
|
||||||
|
import androidx.collection.LruCache
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.constant.AppLog.putDebug
|
import io.legado.app.constant.AppLog.putDebug
|
||||||
import io.legado.app.data.entities.Book
|
import io.legado.app.data.entities.Book
|
||||||
@@ -23,6 +24,33 @@ object ImageProvider {
|
|||||||
BitmapFactory.decodeResource(appCtx.resources, R.drawable.image_loading_error)
|
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<String, Bitmap>(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(
|
suspend fun cacheImage(
|
||||||
book: Book,
|
book: Book,
|
||||||
src: String,
|
src: String,
|
||||||
@@ -45,6 +73,9 @@ object ImageProvider {
|
|||||||
return vFile
|
return vFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*获取图片宽度高度信息
|
||||||
|
*/
|
||||||
suspend fun getImageSize(
|
suspend fun getImageSize(
|
||||||
book: Book,
|
book: Book,
|
||||||
src: String,
|
src: String,
|
||||||
@@ -58,16 +89,23 @@ object ImageProvider {
|
|||||||
return Size(op.outWidth, op.outHeight)
|
return Size(op.outWidth, op.outHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*获取bitmap 使用LruCache缓存
|
||||||
|
*/
|
||||||
fun getImage(
|
fun getImage(
|
||||||
book: Book,
|
book: Book,
|
||||||
src: String,
|
src: String,
|
||||||
width: Int,
|
width: Int,
|
||||||
height: Int
|
height: Int
|
||||||
): Bitmap {
|
): Bitmap {
|
||||||
|
val cacheBitmap = bitmapLruCache.get(src)
|
||||||
|
if (cacheBitmap != null) return cacheBitmap
|
||||||
val vFile = BookHelp.getImage(book, src)
|
val vFile = BookHelp.getImage(book, src)
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
return try {
|
return try {
|
||||||
BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
||||||
|
bitmapLruCache.put(src, bitmap)
|
||||||
|
bitmap
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Coroutine.async {
|
Coroutine.async {
|
||||||
putDebug("${vFile.absolutePath} 解码失败\n$e", e)
|
putDebug("${vFile.absolutePath} 解码失败\n$e", e)
|
||||||
@@ -80,15 +118,22 @@ object ImageProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*获取bitmap 使用LruCache缓存
|
||||||
|
*/
|
||||||
fun getImage(
|
fun getImage(
|
||||||
book: Book,
|
book: Book,
|
||||||
src: String,
|
src: String,
|
||||||
width: Int
|
width: Int
|
||||||
): Bitmap {
|
): Bitmap {
|
||||||
|
val cacheBitmap = bitmapLruCache.get(src)
|
||||||
|
if (cacheBitmap != null) return cacheBitmap
|
||||||
val vFile = BookHelp.getImage(book, src)
|
val vFile = BookHelp.getImage(book, src)
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
return try {
|
return try {
|
||||||
BitmapUtils.decodeBitmap(vFile.absolutePath, width)
|
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width)
|
||||||
|
bitmapLruCache.put(src, bitmap)
|
||||||
|
bitmap
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Coroutine.async {
|
Coroutine.async {
|
||||||
putDebug("${vFile.absolutePath} 解码失败\n$e", e)
|
putDebug("${vFile.absolutePath} 解码失败\n$e", e)
|
||||||
|
|||||||
Reference in New Issue
Block a user