优化
This commit is contained in:
@@ -90,7 +90,7 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
|
||||
* 存储异常和参数信息
|
||||
*/
|
||||
private val paramsMap by lazy {
|
||||
val map = HashMap<String, String>()
|
||||
val map = LinkedHashMap<String, String>()
|
||||
kotlin.runCatching {
|
||||
//获取系统信息
|
||||
map["MANUFACTURER"] = Build.MANUFACTURER
|
||||
@@ -104,6 +104,7 @@ class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
|
||||
e.toString()
|
||||
}
|
||||
map["packageName"] = appCtx.packageName
|
||||
map["heapSize"] = Runtime.getRuntime().maxMemory().toString()
|
||||
//获取app版本信息
|
||||
AppConst.appInfo.let {
|
||||
map["versionName"] = it.versionName
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.legado.app.BuildConfig
|
||||
import io.legado.app.constant.AppConst
|
||||
import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.utils.canvasrecorder.CanvasRecorderFactory
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.getPrefInt
|
||||
import io.legado.app.utils.getPrefLong
|
||||
@@ -37,7 +38,8 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
var clickActionBR = appCtx.getPrefInt(PreferKey.clickActionBR, 1)
|
||||
var themeMode = appCtx.getPrefString(PreferKey.themeMode, "0")
|
||||
var useDefaultCover = appCtx.getPrefBoolean(PreferKey.useDefaultCover, false)
|
||||
var optimizeRender = appCtx.getPrefBoolean(PreferKey.optimizeRender, false)
|
||||
var optimizeRender = CanvasRecorderFactory.isSupport
|
||||
&& appCtx.getPrefBoolean(PreferKey.optimizeRender, false)
|
||||
var recordLog = appCtx.getPrefBoolean(PreferKey.recordLog)
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
@@ -87,8 +89,8 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
PreferKey.useDefaultCover -> useDefaultCover =
|
||||
appCtx.getPrefBoolean(PreferKey.useDefaultCover, false)
|
||||
|
||||
PreferKey.optimizeRender -> optimizeRender =
|
||||
appCtx.getPrefBoolean(PreferKey.optimizeRender, false)
|
||||
PreferKey.optimizeRender -> optimizeRender = CanvasRecorderFactory.isSupport
|
||||
&& appCtx.getPrefBoolean(PreferKey.optimizeRender, false)
|
||||
|
||||
PreferKey.recordLog -> recordLog = appCtx.getPrefBoolean(PreferKey.recordLog)
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ import io.legado.app.model.ReadBook
|
||||
import io.legado.app.ui.book.read.ReadBookActivity
|
||||
import io.legado.app.ui.book.read.page.provider.ChapterProvider
|
||||
import io.legado.app.ui.widget.number.NumberPickerDialog
|
||||
import io.legado.app.utils.canvasrecorder.CanvasRecorderFactory
|
||||
import io.legado.app.utils.dpToPx
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.postEvent
|
||||
import io.legado.app.utils.removePref
|
||||
import io.legado.app.utils.setEdgeEffectColor
|
||||
|
||||
class MoreConfigDialog : BasePrefDialogFragment() {
|
||||
@@ -83,6 +85,10 @@ class MoreConfigDialog : BasePrefDialogFragment() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_config_read)
|
||||
upPreferenceSummary(PreferKey.pageTouchSlop, slopSquare.toString())
|
||||
if (!CanvasRecorderFactory.isSupport) {
|
||||
removePref(PreferKey.optimizeRender)
|
||||
preferenceScreen.removePreferenceRecursively(PreferKey.optimizeRender)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
||||
@@ -35,7 +35,6 @@ 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.longToastOnUi
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
@@ -485,7 +484,6 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
||||
pageDelegate?.onDestroy()
|
||||
curPage.cancelSelect()
|
||||
invalidateTextPage()
|
||||
BitmapPool.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -124,6 +124,7 @@ object LogUtils {
|
||||
}
|
||||
append("WebViewUserAgent=").append(userAgent).append("\n")
|
||||
append("packageName=").append(appCtx.packageName).append("\n")
|
||||
append("heapSize=").append(Runtime.getRuntime().maxMemory()).append("\n")
|
||||
//获取app版本信息
|
||||
AppConst.appInfo.let {
|
||||
append("versionName=").append(it.versionName).append("\n")
|
||||
|
||||
@@ -7,6 +7,7 @@ object CanvasRecorderFactory {
|
||||
|
||||
private val atLeastApi24 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
private val atLeastApi29 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||
val isSupport = atLeastApi24
|
||||
|
||||
// issue 3868
|
||||
fun create(locked: Boolean = false): CanvasRecorder {
|
||||
|
||||
@@ -3,8 +3,9 @@ package io.legado.app.utils.canvasrecorder
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import io.legado.app.utils.canvasrecorder.pools.BitmapPool
|
||||
import com.bumptech.glide.Glide
|
||||
import io.legado.app.utils.canvasrecorder.pools.CanvasPool
|
||||
import splitties.init.appCtx
|
||||
|
||||
class CanvasRecorderImpl : BaseCanvasRecorder() {
|
||||
|
||||
@@ -19,14 +20,14 @@ class CanvasRecorderImpl : BaseCanvasRecorder() {
|
||||
return
|
||||
}
|
||||
if (bitmap == null) {
|
||||
bitmap = BitmapPool.obtain(width, height)
|
||||
bitmap = bitmapPool.get(width, height, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
if (bitmap!!.width != width || bitmap!!.height != height) {
|
||||
if (canReconfigure(width, height)) {
|
||||
if (bitmap!!.isMutable && canReconfigure(width, height)) {
|
||||
bitmap!!.reconfigure(width, height, Bitmap.Config.ARGB_8888)
|
||||
} else {
|
||||
BitmapPool.recycle(bitmap!!)
|
||||
bitmap = BitmapPool.obtain(width, height)
|
||||
bitmapPool.put(bitmap!!)
|
||||
bitmap = bitmapPool.get(width, height, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,12 +58,13 @@ class CanvasRecorderImpl : BaseCanvasRecorder() {
|
||||
override fun recycle() {
|
||||
super.recycle()
|
||||
val bitmap = bitmap ?: return
|
||||
BitmapPool.recycle(bitmap)
|
||||
bitmapPool.put(bitmap)
|
||||
this.bitmap = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val canvasPool = CanvasPool(2)
|
||||
private val bitmapPool = Glide.get(appCtx).bitmapPool
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
package io.legado.app.utils.canvasrecorder.pools
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import io.legado.app.help.globalExecutor
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
object BitmapPool {
|
||||
|
||||
private val reusableBitmaps: MutableSet<Bitmap> = ConcurrentHashMap.newKeySet()
|
||||
|
||||
fun recycle(bitmap: 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 {
|
||||
if (reusableBitmaps.isEmpty()) {
|
||||
return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
val iterator = reusableBitmaps.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val item = iterator.next()
|
||||
if (item.isMutable) {
|
||||
// Check to see it the item can be used for inBitmap.
|
||||
if (canReconfigure(item, width, height)) {
|
||||
// Remove from reusable set so it can't be used again.
|
||||
iterator.remove()
|
||||
item.reconfigure(width, height, Bitmap.Config.ARGB_8888)
|
||||
return item
|
||||
}
|
||||
} else {
|
||||
// Remove from the set if the reference has been cleared.
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
|
||||
private fun canReconfigure(
|
||||
candidate: Bitmap,
|
||||
width: Int,
|
||||
height: Int
|
||||
): Boolean {
|
||||
// From Android 4.4 (KitKat) onward we can re-use if the byte size of
|
||||
// the new bitmap is smaller than the reusable bitmap candidate
|
||||
// allocation byte count.
|
||||
val byteCount: Int = width * height * getBytesPerPixel(candidate.config)
|
||||
return byteCount <= candidate.allocationByteCount
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A helper function to return the byte usage per pixel of a bitmap based on its configuration.
|
||||
*/
|
||||
private fun getBytesPerPixel(config: Bitmap.Config?): Int {
|
||||
return when (config) {
|
||||
Bitmap.Config.ARGB_8888 -> 4
|
||||
Bitmap.Config.RGB_565, Bitmap.Config.ARGB_4444 -> 2
|
||||
Bitmap.Config.ALPHA_8 -> 1
|
||||
else -> 1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user