Horis 1 年間 前
親
コミット
2af4ab0c0a

+ 33 - 3
app/src/main/java/io/legado/app/model/ImageProvider.kt

@@ -26,6 +26,7 @@ import kotlinx.coroutines.withContext
 import splitties.init.appCtx
 import java.io.File
 import java.io.FileOutputStream
+import kotlin.math.min
 
 object ImageProvider {
 
@@ -45,7 +46,14 @@ object ImageProvider {
             }
             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 {
             return bitmap.byteCount
@@ -57,6 +65,11 @@ object ImageProvider {
             oldBitmap: Bitmap,
             newBitmap: Bitmap?
         ) {
+            if (!evicted) {
+                synchronized(this) {
+                    removeCount++
+                }
+            }
             //错误图片不能释放,占位用,防止一直重复获取图片
             if (oldBitmap != errorBitmap) {
                 oldBitmap.recycle()
@@ -68,6 +81,7 @@ object ImageProvider {
     }
 
     fun put(key: String, bitmap: Bitmap) {
+        ensureLruCacheSize(bitmap)
         bitmapLruCache.put(key, bitmap)
     }
 
@@ -88,6 +102,22 @@ object ImageProvider {
         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图片
      */
@@ -167,11 +197,11 @@ object ImageProvider {
             val bitmap = BitmapUtils.decodeBitmap(vFile.absolutePath, width, height)
                 ?: SvgUtils.createBitmap(vFile.absolutePath, width, height)
                 ?: throw NoStackTraceException(appCtx.getString(R.string.error_decode_bitmap))
-            bitmapLruCache.put(vFile.absolutePath, bitmap)
+            put(vFile.absolutePath, bitmap)
             bitmap
         }.onFailure {
             //错误图片占位,防止重复获取
-            bitmapLruCache.put(vFile.absolutePath, errorBitmap)
+            put(vFile.absolutePath, errorBitmap)
         }.getOrDefault(errorBitmap)
     }
 

+ 7 - 1
app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleDialog.kt

@@ -292,7 +292,13 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
                 }
                 ivDelete.setOnClickListener {
                     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)
+                            }
+                        }
                     }
                 }
             }

+ 16 - 3
app/src/main/java/io/legado/app/ui/dict/rule/DictRuleActivity.kt

@@ -140,6 +140,7 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
                 mode = HandleFileContract.FILE
                 allowExtensions = arrayOf("txt", "json")
             }
+
             R.id.menu_import_onLine -> showImportDialog()
             R.id.menu_import_qr -> qrCodeResult.launch()
             R.id.menu_import_default -> viewModel.importDefault()
@@ -150,8 +151,14 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
 
     override fun onMenuItemClick(item: MenuItem): Boolean {
         when (item.itemId) {
-            R.id.menu_enable_selection -> viewModel.enableSelection(*adapter.selection.toTypedArray())
-            R.id.menu_disable_selection -> viewModel.disableSelection(*adapter.selection.toTypedArray())
+            R.id.menu_enable_selection -> {
+                viewModel.enableSelection(*adapter.selection.toTypedArray())
+            }
+
+            R.id.menu_disable_selection -> {
+                viewModel.disableSelection(*adapter.selection.toTypedArray())
+            }
+
             R.id.menu_export_selection -> exportResult.launch {
                 mode = HandleFileContract.EXPORT
                 fileData = HandleFileContract.FileData(
@@ -185,7 +192,13 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
     }
 
     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) {

+ 0 - 1
app/src/main/java/io/legado/app/ui/dict/rule/DictRuleAdapter.kt

@@ -143,7 +143,6 @@ class DictRuleAdapter(context: Context, var callBack: CallBack) :
             ivDelete.setOnClickListener {
                 getItem(holder.layoutPosition)?.let {
                     callBack.delete(it)
-                    selected.remove(it)
                 }
             }
         }