优化
This commit is contained in:
@@ -26,6 +26,7 @@ import kotlinx.coroutines.withContext
|
|||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
object ImageProvider {
|
object ImageProvider {
|
||||||
|
|
||||||
@@ -45,7 +46,14 @@ object ImageProvider {
|
|||||||
}
|
}
|
||||||
return AppConfig.bitmapCacheSize * M
|
return AppConfig.bitmapCacheSize * M
|
||||||
}
|
}
|
||||||
val bitmapLruCache = object : LruCache<String, Bitmap>(cacheSize) {
|
|
||||||
|
val bitmapLruCache = BitmapLruCache()
|
||||||
|
|
||||||
|
class BitmapLruCache : LruCache<String, Bitmap>(cacheSize) {
|
||||||
|
|
||||||
|
private var removeCount = 0
|
||||||
|
|
||||||
|
val count get() = putCount() + createCount() - evictionCount() - removeCount
|
||||||
|
|
||||||
override fun sizeOf(filePath: String, bitmap: Bitmap): Int {
|
override fun sizeOf(filePath: String, bitmap: Bitmap): Int {
|
||||||
return bitmap.byteCount
|
return bitmap.byteCount
|
||||||
@@ -57,6 +65,11 @@ object ImageProvider {
|
|||||||
oldBitmap: Bitmap,
|
oldBitmap: Bitmap,
|
||||||
newBitmap: Bitmap?
|
newBitmap: Bitmap?
|
||||||
) {
|
) {
|
||||||
|
if (!evicted) {
|
||||||
|
synchronized(this) {
|
||||||
|
removeCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
//错误图片不能释放,占位用,防止一直重复获取图片
|
//错误图片不能释放,占位用,防止一直重复获取图片
|
||||||
if (oldBitmap != errorBitmap) {
|
if (oldBitmap != errorBitmap) {
|
||||||
oldBitmap.recycle()
|
oldBitmap.recycle()
|
||||||
@@ -68,6 +81,7 @@ object ImageProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun put(key: String, bitmap: Bitmap) {
|
fun put(key: String, bitmap: Bitmap) {
|
||||||
|
ensureLruCacheSize(bitmap)
|
||||||
bitmapLruCache.put(key, bitmap)
|
bitmapLruCache.put(key, bitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +102,22 @@ object ImageProvider {
|
|||||||
return bitmap
|
return bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ensureLruCacheSize(bitmap: Bitmap) {
|
||||||
|
val lruMaxSize = bitmapLruCache.maxSize()
|
||||||
|
val lruSize = bitmapLruCache.size()
|
||||||
|
val byteCount = bitmap.byteCount
|
||||||
|
val size = if (byteCount > lruMaxSize) {
|
||||||
|
min(256 * M, (byteCount * 1.3).toInt())
|
||||||
|
} else if (lruSize + byteCount > lruMaxSize && bitmapLruCache.count < 5) {
|
||||||
|
min(256 * M, (lruSize + byteCount * 1.3).toInt())
|
||||||
|
} else {
|
||||||
|
lruMaxSize
|
||||||
|
}
|
||||||
|
if (size > lruMaxSize) {
|
||||||
|
bitmapLruCache.resize(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*缓存网络图片和epub图片
|
*缓存网络图片和epub图片
|
||||||
*/
|
*/
|
||||||
@@ -167,11 +197,11 @@ object ImageProvider {
|
|||||||
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
|
||||||
?: SvgUtils.createBitmap(vFile.absolutePath, width, height)
|
?: SvgUtils.createBitmap(vFile.absolutePath, width, height)
|
||||||
?: throw NoStackTraceException(appCtx.getString(R.string.error_decode_bitmap))
|
?: throw NoStackTraceException(appCtx.getString(R.string.error_decode_bitmap))
|
||||||
bitmapLruCache.put(vFile.absolutePath, bitmap)
|
put(vFile.absolutePath, bitmap)
|
||||||
bitmap
|
bitmap
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
//错误图片占位,防止重复获取
|
//错误图片占位,防止重复获取
|
||||||
bitmapLruCache.put(vFile.absolutePath, errorBitmap)
|
put(vFile.absolutePath, errorBitmap)
|
||||||
}.getOrDefault(errorBitmap)
|
}.getOrDefault(errorBitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -292,7 +292,13 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
|
|||||||
}
|
}
|
||||||
ivDelete.setOnClickListener {
|
ivDelete.setOnClickListener {
|
||||||
getItem(holder.layoutPosition)?.let { item ->
|
getItem(holder.layoutPosition)?.let { item ->
|
||||||
viewModel.del(item)
|
alert(R.string.draw) {
|
||||||
|
setMessage(getString(R.string.sure_del) + "\n" + item.name)
|
||||||
|
noButton()
|
||||||
|
yesButton {
|
||||||
|
viewModel.del(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
|
|||||||
mode = HandleFileContract.FILE
|
mode = HandleFileContract.FILE
|
||||||
allowExtensions = arrayOf("txt", "json")
|
allowExtensions = arrayOf("txt", "json")
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_import_onLine -> showImportDialog()
|
R.id.menu_import_onLine -> showImportDialog()
|
||||||
R.id.menu_import_qr -> qrCodeResult.launch()
|
R.id.menu_import_qr -> qrCodeResult.launch()
|
||||||
R.id.menu_import_default -> viewModel.importDefault()
|
R.id.menu_import_default -> viewModel.importDefault()
|
||||||
@@ -150,8 +151,14 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
|
|||||||
|
|
||||||
override fun onMenuItemClick(item: MenuItem): Boolean {
|
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_enable_selection -> viewModel.enableSelection(*adapter.selection.toTypedArray())
|
R.id.menu_enable_selection -> {
|
||||||
R.id.menu_disable_selection -> viewModel.disableSelection(*adapter.selection.toTypedArray())
|
viewModel.enableSelection(*adapter.selection.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.menu_disable_selection -> {
|
||||||
|
viewModel.disableSelection(*adapter.selection.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
R.id.menu_export_selection -> exportResult.launch {
|
R.id.menu_export_selection -> exportResult.launch {
|
||||||
mode = HandleFileContract.EXPORT
|
mode = HandleFileContract.EXPORT
|
||||||
fileData = HandleFileContract.FileData(
|
fileData = HandleFileContract.FileData(
|
||||||
@@ -185,7 +192,13 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun delete(rule: DictRule) {
|
override fun delete(rule: DictRule) {
|
||||||
viewModel.delete(rule)
|
alert(R.string.draw) {
|
||||||
|
setMessage(getString(R.string.sure_del) + "\n" + rule.name)
|
||||||
|
noButton()
|
||||||
|
yesButton {
|
||||||
|
viewModel.delete(rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun edit(rule: DictRule) {
|
override fun edit(rule: DictRule) {
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ class DictRuleAdapter(context: Context, var callBack: CallBack) :
|
|||||||
ivDelete.setOnClickListener {
|
ivDelete.setOnClickListener {
|
||||||
getItem(holder.layoutPosition)?.let {
|
getItem(holder.layoutPosition)?.let {
|
||||||
callBack.delete(it)
|
callBack.delete(it)
|
||||||
selected.remove(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user