一般来说,图片是APP占用内存高的主要原因,所以优化图片的内存占用是避免OOM的根本手段。对于图片占用的内存,我们可能总有这样的误区:图片本身所占的存储空间越小,占用的内存越小。所以认为只要将图片进行压缩,就相当于减小了内存占用。其实这是不对的,图片占用的存储空间大小与所占内存大小没有直接关系。
既然与内存没有关系,那压缩图片有什么意义呢?对于APK而言,压缩图片是为了减小APK的体积,而对于需要网络请求的图片,压缩则是为了更快的网络响应。
所以优化之前需要清楚2个基本原则:
- 图片占用内存的大小与图片本身的大小没有直接关系;
- WebP格式的图片虽然小,但占用的内存和其他格式无差别;
图片占用内存的大小
memorySize ≈ width * height * 每个像素需要的字节数
优化策略
既然需要的内存公式已得到,那优化就显而易见了,无非就是减小的这三个参数的值,具体的策略如下:
这里我们将图片分为2种情况来探讨:
drawable中的图片
单独探讨这种情况,是因为Android系统会对drawable中的图片进行缩放,缩放系数与设置的屏幕分辨率和drawable所表示的分辨率有关,具体的公式如下:
scale = 设备分辨率 / 资源目录分辨率 如:1080x1920的图片显示xhdpi中的图片,scale = 480 / 320 = 1.5
所以此时图片占用的内存大小为:
memorySize ≈ (width * scale) * (height * scale) * 每个像素需要的字节数
≈ width * height * scale ^ 2 * 每个像素需要的字节数
具体的缩放过程可参考Android中Bitmap内存优化
这里我们只探讨一下scale系数的影响因素:设备分辨率和资源目录分辨率。至于其他的可变因子会在另一种情况中介绍。设备分辨率我们没法改变,所以影响因素只有资源目录分辨率,也就是说,同一张图片,放在不同的drawable中,占用的内存大小不同。从公式可看出,使用同一个设备时,drawable表示的分辨率越高,则图片占用的内存越小,反之越大。所以,在做图片的兼容性时,如果只想使用一张图片,则应使用3倍甚至4倍的图片(3倍是主流机型,但在4倍手机上会被放大,图片可能失真),这样在低分辨率的手机上,不仅显示清晰,而且系统会