Android 图片加载性能优化总结

上传人:豆浆 文档编号:11121677 上传时间:2017-10-12 格式:DOCX 页数:54 大小:499.70KB
返回 下载 相关 举报
Android 图片加载性能优化总结_第1页
第1页 / 共54页
Android 图片加载性能优化总结_第2页
第2页 / 共54页
Android 图片加载性能优化总结_第3页
第3页 / 共54页
Android 图片加载性能优化总结_第4页
第4页 / 共54页
Android 图片加载性能优化总结_第5页
第5页 / 共54页
点击查看更多>>
资源描述

《Android 图片加载性能优化总结》由会员分享,可在线阅读,更多相关《Android 图片加载性能优化总结(54页珍藏版)》请在金锄头文库上搜索。

1、Android 图片加载性能优化总结一、Android Bitmap 加载大尺寸图片优化: 压缩原因:1.imageview 大小如果是 200*300 那么加载个 2000*3000 的图片到内存中显然是浪费可耻滴行为;2.最重要的是图片过大时直接加载原图会造成 OOM 异常(out of memory 内存溢出)所以一般对于大图我们需要进行下压缩处理看不懂英文的话木有关系,本篇会有介绍主要处理思路是:1.获取图片的像素宽高( 不加载图片至内存中,所以不会占用资源)2.计算需要压缩的比例3.按将图片用计算出的比例压缩,并加载至内存中使用官网大图片加载教程(上面网址里的)对应代码就是:/* 获

2、取压缩后的图片* param res* param resId* param reqWidth 所需图片压缩尺寸最小宽度* param reqHeight 所需图片压缩尺寸最小高度* return*/public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) / 首先不加载图片 ,仅获取图片尺寸final BitmapFactory.Options options = new BitmapFactory.Options();/ 当 inJu

3、stDecodeBounds 设为 true 时,不会加载图片仅获取图片尺寸信息options.inJustDecodeBounds = true;/ 此时仅会将图片信息会保存至 options 对象内,decode 方法不会返回bitmap 对象BitmapFactory.decodeResource(res, resId, options);/ 计算压缩比例 ,如 inSampleSize=4 时,图片会压缩成原图的 1/4options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);/ 当 inJus

4、tDecodeBounds 设为 false 时,BitmapFactory.decode.就会返回图片对象了options. inJustDecodeBounds = false;/ 利用计算的比例值获取压缩后的图片对象return BitmapFactory.decodeResource(res, resId, options);代码详解:核心方法是 BitmapFactory.decode.(., options).的意思是此外还有一系列的 decodeFile/decodeStream 等等方法,都是利用options 灵活解析获取图片 ,只不过解析图片的来源不同罢了,比如网络图片获取

5、,一般就是解析字节流信息然后decode 获取图片实例Options 是图片配置信息,参数详细介绍下:inJustDecodeBounds 是否只解析边界设为 true 时去 decode 获取图片,只会加载像素宽高信息设为 false 时 decode 则会完全加载图片inSampleSize 压缩比例 比如原图 200*300,如果值是 2 时会压缩成 100*150; 是 4 则图片压缩成50*75 最好是 2 的幂数,比如 2 4 8 16 .outHeight 图片原高度outWidth 图片原宽度其他参数自行研究,这里暂时只用到这几个decodeSampledBitmapFromR

6、esource 方法内的三段代码对应上面的三步流程难点在于中间那步,压缩比例的计算, 官网同样提供了个 calculateInSampleSize 方法其中 reqWidth 和 reqHeight 是所需图片限定最小宽高值/* 计算压缩比例值* param options 解析图片的配置信息* param reqWidth 所需图片压缩尺寸最小宽度* param reqHeight 所需图片压缩尺寸最小高度* return*/public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth,

7、 int reqHeight) / 保存图片原宽高值final int height = options. outHeight;final int width = options. outWidth;/ 初始化压缩比例为 1int inSampleSize = 1;/ 当图片宽高值任何一个大于所需压缩图片宽高值时,进入循环计算系统if (height reqHeight | width reqWidth) final int halfHeight = height / 2;final int halfWidth = width / 2;/ 压缩比例值每次循环两倍增加,/ 直到原图宽高值的一半除

8、以压缩值后都大于所需宽高值为止while (halfHeight / inSampleSize) = reqHeight& (halfWidth / inSampleSize) = reqWidth) inSampleSize *= 2;return inSampleSize;利用此方法获取到所需压缩比例值,最终获取到压缩后的图片以上代码能够看懂的话,下面这段/*扯淡*/ 可以跳过逻辑是将原图宽高一半一半的缩减,一直减到宽高都小于自己设定的限定宽高时为止,测试的时候问题来了原图 400*300,我限定值 200*150,if 满足进入,while 循环第一次,400/2/1=200 不满足 的

9、条件结束循环,最终返回了个 inSampleSize=1 给我马丹我限定值正好是原图的一半啊,你应该返回给我 2 啊你特么最后返回个 1 给我,那压缩处理后的图还是 400*300!当我将限定值稍微改一下变成 195*145 稍微降低一点点时 if 满足进入,while 循环第一次,400/2/1195 满足 然后压缩比例 1*2 变成了 2,在下一次 while 循环时不满足条件结束,最后返回比例值 2 满足压缩预期官网的这个方法是: 将图片一半一半的压缩, 直到压缩成成大于所需宽高数的那个最低值大于 不是大于等于,所以就会出现我上面那种情况, 我觉得方法不是太好 = = 能满足压缩的需求,

10、但是压缩的比例不够准确所以最好改成大于等于,如下( 个人意见,仅供参考,在实际压缩中很少遇到恰巧等于的这个情况,所以 和= 差别也不大额看我这扯扯淡就当对计算比例的逻辑加深个理解吧)while (halfHeight / inSampleSize) = reqHeight& (halfWidth / inSampleSize) = reqWidth) inSampleSize *= 2;优化:还是上面例子,如果限定了 200*150,而原图是 390*290 会是个啥情况?还是第一次 while 循环,390/2/1 结果是 195 不满足200 的情况,结束循环, 比例值为 1,最后图片压缩

11、成 400*300虽然压缩一次以后没有满足大于所需宽高,但是和所需宽高很接近啊!能不能做一个获取压缩成最接近所需宽高数的比例值呢?我也不知道= = 回头可以慢慢研究, 这个接近 的定义比较模糊,不好掌握找了几个有名的图片加载开源框架发现也都没有这种处理- -不知道是这样设计是不需要呢,还是没啥用呢以上,图片的像素大小已经做了缩放, 但是图片的大小除了和像素有关, 还和色彩样式有关不同的样式决定了图片单个像素占的字节数比如,图片默认的色彩样式为 ARGB_8888,每个像素占 4byte(字节)大小可以看到一共有四种色彩样式ALPHA_8 每个像素只要 1 字节可惜只能代表透明度, 没有颜色属性

12、ARGB_4444 每个像素要 2 字节带透明度的颜色可惜官方不推荐使用了ARGB_8888 每个像素要 4 字节带透明度的颜色, 默认色样RGB_565 每个像素要 2 字节 不带透明度的颜色默认为 ARGB_8888,如果想丧心病狂的继续减少图片所占大小不需要透明度参数的话,那就可以把色彩样式设为 RGB_565设置方法是在 BitmapFactory.decode.获取图片事例时修改配置参数的 inPreferredConfig 参数opts.inPreferredConfig = Bitmap.Config. RGB_565 ;想亲自撸一撸试一试压缩图片了吧?要注意点问题,如果用 re

13、s 包下图片测试的话, 你会发现有图片尺寸有点混乱那是因为在 drawable-*dpi 文件夹中的图片会根据对应对应的屏幕密度值不同自动进行一定的缩放,比如放在 drawable-hdpi 里的图片, 直接不经过压缩 BitmapFactor.decode.出来,会发现 bitmap 的宽高值是原图的 2/3,测试的时候图片记得放在 drawable 包下(没有的话自己 res 下新建一个),否则你会被奇怪的宽高值弄凌乱的,具体变化原因参考源代码处理,或者网上搜搜看。还有就是 BitmapFactory.decodeStream 方法会偶尔解析图片失败(好像是安卓低版本的一个 bug),此时

14、推荐做法是将流转换为字节流处理,然后利用decodeByteArray 方法获取图片。二、Android 加载多张图片的缓存处理一般少量图片是很少出现 OOM 异常的,除非单张图片过大 那么就可以用教程一里面的方法了通常应用场景是 listview 列表加载多张图片,为了提高效率一般要缓存一部分图片,这样方便再次查看时能快速显示不用重新下载图片但是手机内存是很有限的当缓存的图片越来越多, 即使单张图片不是很大, 不过数量太多时仍然会出现 OOM 的情况了本篇则是讨论多张图片的处理问题图片缓存的一般处理是1.建立一个图片缓存池, 用于存放图片对应的 bitmap 对象2.在显示的时候, 比如 l

15、istview 对应适配器的 getView 方法里进行加载图片的工作, 先从缓存池通过 url 的 key 值取,如果取到图片了直接显示,如果获取不到再建立异步线程去下载图片(下载好后同时保存至图片缓存池并显示 )但是缓存池不能无限大啊不然就会异常了, 所以通常我们要对缓存池进行一定控制需要有两个特性: 总大小有个限制,不然里面存放无限多的图片时会内存溢出 OOM 异常当大小达到上限后,再添加图片时,需要线程池能够智能化的回收移除池内一部分图片,这样才能保证新图片的显示保存异步线程下载图片神马的简单,网上异步下载任务的代码一大堆 ,下载以后流数据直接decode 成 bitmap 图片即可难点在与这个图片缓存池的设计,现在网上的实现主要有两种1.软引用/弱引用2.LruCache-拓展: java 中 4 种引用分类强引用平常使用的基本都是强引用,除非主动释放(图片的回收,或者=null 赋值为空等),否则会一直保存对象到内存溢出为止软引用 SoftReference在系统内存不够时,会自动释放部分软引用所指对象弱引用 WeakReference系统偶尔回收扫描时发现弱引用则释放对象,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号