基于V3.4.6和V3.5.1版本的对比
一、针对图片资源的apk瘦身
1、把大图转换为webp格式,以及删除无用的图片资源减小图片占用
2、vectorDrawable的使用:(5.0引入的,以前的版本可以使用兼容包)
好处:1、可以任意缩放而不会失真,仅仅需要一个文件,就能动态生成对应分辨率的图片。
2、文件一般较小,省去很多资源。而且占用内存非常小,性能高。
缺点:没有图片表达的色彩丰富,只作为简单规则图片的替换方式。
image.png
不过单个图片的内存占用前后变化不大,作为减少apk大小更有优势。
image.png image.png
3、开启shrinkResources编译时删除无用资源文件和图片:
image.png
优化后apk大小比较:apk包的大小由68.8MB缩减为51.3MB,比原来减少了25%
image.png
二、尺寸压缩之后内存占用对比
根据图片的宽高生成对应的缩放系数,再根据该系数加载对应的bitmap到内存中:
fun getLocalBitmapFromResFolder(context: Context?, resId: Int, reqWidth: Int, reqHeight: Int): Bitmap? {
val opts = BitmapFactory.Options()
opts.inJustDecodeBounds = true
var bitmap: Bitmap?
try {
// BitmapFactory.decodeResource(context?.resources, resId, opts)
Log.d("ImageViewUtils:", BitmapFactory.decodeResource(context?.resources, resId).allocationByteCount.toString())
} catch (e: OutOfMemoryError) {
e.printStackTrace()
System.gc()
return null
} catch (e: Exception) {
e.printStackTrace()
return null
}
opts.inPreferredConfig = Bitmap.Config.RGB_565
opts.inTempStorage = ByteArray(10 * 1024 * 1024)
try {
BitmapFactory.decodeResource(context?.resources, resId, opts)
Log.d("ImageViewUtils:原始图的宽高",opts.outWidth.toString()+","+opts.outHeight)
} catch (e: OutOfMemoryError) {
e.printStackTrace()
System.gc()
return null
} catch (e: Exception) {
e.printStackTrace()
return null
}
try {
opts.inSampleSize = calculateInSampleSize(opts, reqWidth, reqHeight)
Log.i("ImageViewUtils:", "inSampleSize " + opts.inSampleSize)
opts.inJustDecodeBounds = false
bitmap = BitmapFactory.decodeResource(context?.resources, resId, opts)
Log.i("ImageViewUtils:压缩后的宽高", "w:" + bitmap.width + " h:" + bitmap.height)
Log.d("ImageViewUtils:",bitmap.byteCount.toString())
} catch (outOfMemoryError: OutOfMemoryError) {
outOfMemoryError.printStackTrace()
System.gc()
return null
}
return bitmap
}
//计算缩放系数,是2的倍数
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
val height = options.outHeight
val width = options.outWidth
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
val halfHeight = height / 2
val halfWidth = width / 2
while (halfHeight / inSampleSize > reqHeight && halfWidth / inSampleSize > reqWidth) {
inSampleSize *= 2
}
}
return inSampleSize
}
使用RGB_565格式替代默认的ARGB_8888,能减少一半的开销,一个像素占用2个字节,而ARGB_8888一个像素占用4个字节,如果图片对alpha要求不高,是一个不错的选择。
相同图片占用堆内存比较:占用内存字节数缩减为原来的1/4
优化前:
图片
优化后:
image.png
·
网友评论