Horis 2 years ago
parent
commit
8570ab823d

+ 2 - 0
app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt

@@ -31,6 +31,7 @@ import io.legado.app.ui.book.read.page.provider.ChapterProvider
 import io.legado.app.ui.book.read.page.provider.LayoutProgressListener
 import io.legado.app.ui.book.read.page.provider.TextPageFactory
 import io.legado.app.utils.activity
+import io.legado.app.utils.canvasrecorder.pools.BitmapPool
 import io.legado.app.utils.invisible
 import io.legado.app.utils.showDialogFragment
 import io.legado.app.utils.throttle
@@ -461,6 +462,7 @@ class ReadView(context: Context, attrs: AttributeSet) :
         pageDelegate?.onDestroy()
         curPage.cancelSelect()
         invalidateTextPage()
+        BitmapPool.clear()
     }
 
     /**

+ 4 - 5
app/src/main/java/io/legado/app/utils/canvasrecorder/CanvasRecorderImpl.kt

@@ -16,14 +16,14 @@ class CanvasRecorderImpl : BaseCanvasRecorder() {
 
     private fun init(width: Int, height: Int) {
         if (bitmap == null) {
-            bitmap = bitmapPool.obtain(width, height)
+            bitmap = BitmapPool.obtain(width, height)
         }
         if (bitmap!!.width != width || bitmap!!.height != height) {
             if (canReconfigure(width, height)) {
                 bitmap!!.reconfigure(width, height, Bitmap.Config.ARGB_8888)
             } else {
-                bitmapPool.recycle(bitmap!!)
-                bitmap = bitmapPool.obtain(width, height)
+                BitmapPool.recycle(bitmap!!)
+                bitmap = BitmapPool.obtain(width, height)
             }
         }
     }
@@ -54,13 +54,12 @@ class CanvasRecorderImpl : BaseCanvasRecorder() {
     override fun recycle() {
         super.recycle()
         val bitmap = bitmap ?: return
-        bitmapPool.recycle(bitmap)
+        BitmapPool.recycle(bitmap)
         this.bitmap = null
     }
 
     companion object {
         private val canvasPool = CanvasPool(2)
-        private val bitmapPool = BitmapPool()
     }
 
 }

+ 36 - 5
app/src/main/java/io/legado/app/utils/canvasrecorder/pools/BitmapPool.kt

@@ -1,15 +1,46 @@
 package io.legado.app.utils.canvasrecorder.pools
 
 import android.graphics.Bitmap
-import java.lang.ref.SoftReference
+import io.legado.app.help.globalExecutor
 import java.util.concurrent.ConcurrentHashMap
 
-class BitmapPool {
+object BitmapPool {
 
-    private val reusableBitmaps: MutableSet<SoftReference<Bitmap>> = ConcurrentHashMap.newKeySet()
+    private val reusableBitmaps: MutableSet<Bitmap> = ConcurrentHashMap.newKeySet()
 
     fun recycle(bitmap: Bitmap) {
-        reusableBitmaps.add(SoftReference(bitmap))
+        reusableBitmaps.add(bitmap)
+        trimSize()
+    }
+
+    fun clear() {
+        if (reusableBitmaps.isEmpty()) {
+            return
+        }
+        globalExecutor.execute {
+            val iterator = reusableBitmaps.iterator()
+            while (iterator.hasNext()) {
+                val item = iterator.next()
+                iterator.remove()
+                item.recycle()
+            }
+        }
+    }
+
+    private fun trimSize() {
+        globalExecutor.execute {
+            var byteCount = 0
+            val iterator = reusableBitmaps.iterator()
+            while (iterator.hasNext()) {
+                val item = iterator.next()
+                if (byteCount > 64 * 1024 * 1024) {
+                    iterator.remove()
+                    item.recycle()
+                } else {
+                    byteCount += item.byteCount
+                }
+            }
+        }
     }
 
     fun obtain(width: Int, height: Int): Bitmap {
@@ -18,7 +49,7 @@ class BitmapPool {
         }
         val iterator = reusableBitmaps.iterator()
         while (iterator.hasNext()) {
-            val item = iterator.next().get() ?: continue
+            val item = iterator.next()
             if (item.isMutable) {
                 // Check to see it the item can be used for inBitmap.
                 if (canReconfigure(item, width, height)) {