}
3. 缓存池大小
Android LruCache(Picasso内存缓存)
现在很多图片加载组件都不仅仅是使用软引用或者弱引用了,实际上类似Glide 默认使用的事LruCache,因为软引用 弱引用都比较难以控制,使用LruCache可以实现比较精细的控制,而默认缓存池设置太大了会导致浪费内存,设置小了又会导致图片经常被回收,所以需要根据每个App的情况,以及设备的分辨率,内存计算出一个比较合理的初始值,可以参考Glide的做法。
4 想办法减少 Bitmap 内存占用:
4.1 Jpg 和 Png
jpg 是一种有损压缩的图片存储格式,而 png 则是 无损压缩的图片存储格式,显而易见,jpg 会比 png 小.
Bitmap 在内存当中占用的大小其实取决于:
色彩格式,前面我们已经提到,如果是 ARGB8888 那么就是一个像素4个字节,如果是 RGB565 那就是2个字节
原始文件存放的资源目录(是 hdpi 还是 xxhdpi 可不能傻傻分不清楚哈)
目标屏幕的密度(所以同等条件下,红米在资源方面消耗的内存肯定是要小于三星S6的)
如果仅仅是为了 Bitmap 读到内存中的大小而考虑的话,jpg 也好 png 也好,没有什么实质的差别;二者的差别主要体现在:
alpha 你是否真的需要?如果需要 alpha 通道,那么没有别的选择,用 png。
你的图色值丰富还是单调?就像刚才提到的,如果色值丰富,那么用jpg,如果作为按钮的背景,请用 png。
对安装包大小的要求是否非常严格?如果你的 app 资源很少,安装包大小问题不是很凸显,看情况选择 jpg 或者 png(不过,我想现在对资源文件没有苛求的应用会很少吧。。)
目标用户的 cpu 是否强劲?jpg 的图像压缩算法比 png 耗时。这方面还是要酌情选择,前几年做了一段时间 Cocos2dx,由于资源非常多,项目组要求统一使用 png,可能就是出于这方面的考虑。
4.2 使用 inSampleSize (采样率压缩)
这个方法主要用在图片资源本身较大,或者适当地采样并不会影响视觉效果的条件下,这时候我们输出地目标可能相对较小,对图片分辨率、大小要求不是非常的严格。
既然图片最终是要被模糊的,也看不太情况,还不如直接用一张采样后的图片,如果采样率为 2,那么读出来的图片只有原始图片的 1/4 大小:
1 BitmapFactory.Options options = new Options();
2 options.inSampleSize = 2;
3 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId, options);
4.3 使用矩阵
大图小用用采样,小图大用用矩阵。
还是用前面模糊图片的例子,我们不是采样了么?内存是小了,可是图的尺寸也小了啊,我要用 Canvas 绘制这张图可怎么办?当然是用矩阵了:
1 Matrix matrix = new Matrix();
2 matrix.preScale(2, 2, 0f, 0f);
3 //如果使用直接替换矩阵的话,在Nexus6 5.1.1上必须关闭硬件加速
4 canvas.concat(matrix);
5 canvas.drawBitmap(bitmap, 0,0, paint);
需要注意的是,在使用搭载 5.1.1 原生系统的 Nexus6 进行测试时发现,如果使用 Canvas 的 setMatrix 方法,可能会导致与矩阵相关的元素的绘制存在问题,本例当中如果使用 setMatrix 方法,bitmap 将不会出现在屏幕上。因此请尽量使用 canvas 的 scale、rotate 这样的方法,或者使用 concat 方法。
1 Matrix matrix = new Matrix();
2 matrix.preScale(2, 2, 0, 0);
3 canvas.drawBitmap(bitmap, matrix, paint);
这样,绘制出来的图就是放大以后的效果了,不过占用的内存却仍然是我们采样出来的大小。
如果我要把图片放到 ImageView 当中呢?一样可以,请看:
1 Matrix matrix = new Matrix();
2 matrix.postScale(2, 2, 0, 0);
3 imageView.setImageMatrix(matrix);
4 imageView.setScaleType(ScaleType.MATRIX);
5 imageView.setImageBitmap(bitmap);
4.4 合理选择Bitmap的像素格式
其实前面我们已经多次提到这个问题。
ARGB8888格式的图片,每像素占用 4 Byte,而 RGB565则是 2 Byte。我们先看下有多少种格式可选:
ALPHA_8
只有一个alpha通道
ARGB_4444
这个从API 13开始不建议使用,因为质量太差
ARGB_8888
ARGB四个通道,每个通道8bit
RGB_565
每个像素占2Byte,其中红色占5bit,绿色占6bit,蓝色占5bit
这几个当中,
ALPHA8 没必要用,因为我们随便用个颜色就可以搞定的。
ARGB4444 虽然占用内存只有 ARGB8888 的一半,不过已经被官方嫌弃,失宠了。。『又要占省内存,又要看着爽,臣妾做不到啊T T』。
ARGB8888 是最常用的,大家应该最熟悉了。
RGB565 看到这个,我就看到了资源优化配置无处不在,这个绿色。。(不行了,突然好邪恶XD),其实如果不需要 alpha 通道,特别是资源本身为 jpg 格式的情况下,用这个格式比较理想。