免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1401 | 回复: 0

[Android] 关于Android加载图片OOM的思考 [复制链接]

论坛徽章:
59
2015七夕节徽章
日期:2015-08-24 11:17:25ChinaUnix专家徽章
日期:2015-07-20 09:19:30每周论坛发贴之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38荣誉版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年纪念徽章
日期:2015-07-20 11:05:27IT运维版块每日发帖之星
日期:2015-07-20 11:05:34操作系统版块每日发帖之星
日期:2015-07-20 11:05:36程序设计版块每日发帖之星
日期:2015-07-20 11:05:40数据库技术版块每日发帖之星
日期:2015-07-20 11:05:432015年辞旧岁徽章
日期:2015-07-20 11:05:44
发表于 2015-07-28 13:02 |显示全部楼层
大家都知道,使用Android加载图片时,一般来说加载几个图片都容易OOM,但是Android手机的相册似乎没有这个问题。
思索了很久没有找到办法,和一个哥们讨论次问题时他给出个解决办法:
(下面的文字转自:http://blog.sina.com.cn/s/blog_7139b0e30100xklb.html,所以本博文属于转载)
写Android代码也有那么三四个月的时间了,也一直都是菜鸟,很多东西都只是拿来就用,也没有想太多的细节问题。    之前在程序中遇到图片资源的时候,总是使用
BitmapFactory.decodeResource
来设置图片资源,也没发现什么问题。前段时间在写一个动态壁纸程序的时候,可能图片资源比较多,毕竟手机内存还是有限的,程序跑起来有时会
out of Memory
异常。
后来改用BitmapFactory.decodeStream方法,好像能解决问题。
    后来在程序中去测试对比了一下,发现还是有比较大的差别的。同样是加载十张图片,我们先看看使用BitmapFactory.decodeResource后的内存占用情况:

    //加载图片前的空余内存空间

    long freeStart = Runtime.getRuntime().freeMemory();

    bubble2 = BitmapFactory.decodeResource(resources, R.drawable.bubble2);

    bubble5 = BitmapFactory.decodeResource(resources, R.drawable.bubble5);

    bubble_2 = BitmapFactory.decodeResource(resources, R.drawable.bubble_2);

    speeding = BitmapFactory.decodeResource(resources, R.drawable.speeding);

    slowing = BitmapFactory.decodeResource(resources, R.drawable.slowing);

    resee = BitmapFactory.decodeResource(resources, R.drawable.resee);

    network = BitmapFactory.decodeResource(resources, R.drawable.network5);

    audio = BitmapFactory.decodeResource(resources, R.drawable.audio);

    eye_back = BitmapFactory.decodeResource(resources, R.drawable.eye_back);

    eye = BitmapFactory.decodeResource(resources, R.drawable.eye);

    //加载图片后的空余内存空间

    long freeEnd = Runtime.getRuntime().freeMemory();

  System.out.println("freeStart:"+freeStart+"\nfreeEnd:"+freeEnd+"\n 相差:"+(freeStart-freeEnd));

   运行结果是:

   


   

    再来看看使用BitmapFactory.decodeStream的情况:


public Bitmap readBitmap(Context context, int id){

     BitmapFactory.Options opt = new BitmapFactory.Options();

     opt.inPreferredConfig=Bitmap.Config.RGB_565;//表示16位位图 565代表对应三原色占的位数

     opt.inInputShareable=true;

     opt.inPurgeable=true;//设置图片可以被回收

     InputStream is = context.getResources().openRawResource(id);


     return BitmapFactory.decodeStream(is, null, opt);

}     



//加载图片前的空余内存空间

long freeStart = Runtime.getRuntime().freeMemory();

bubble2 = utils.readBitmap(context, R.drawable.bubble2);

bubble5 = utils.readBitmap(context, R.drawable.bubble5);

bubble_2 = utils.readBitmap(context, R.drawable.bubble_2);

speeding = utils.readBitmap(context, R.drawable.speeding);

slowing = utils.readBitmap(context, R.drawable.slowing);

resee = utils.readBitmap(context, R.drawable.resee);

network = utils.readBitmap(context, R.drawable.network5);

audio = utils.readBitmap(context, R.drawable.audio);

eye_back = utils.readBitmap(context, R.drawable.eye_back);

eye = utils.readBitmap(context, R.drawable.eye);

//加载图片后的空余内存空间

long freeEnd = Runtime.getRuntime().freeMemory();

System.out.println("freeStart:"+freeStart+"\nfreeEnd:"+freeEnd+"\n 相差:"+(freeStart-freeEnd));


        运行结果是:

        

              从两个的运行结果中可以看出,使用
BitmapFactory.decodeResource
来设置图片资源要消耗更多的内存,如果程序中的图片资源很多的话,那这个内存就很客观啦。主要因为是
BitmapFactory.decodeResource
是通过Java层来createBitmap来完成图片的加载,增加了java层的内存消耗。而
BitmapFactory.decodeStream
则是直接调用了JNI,避免了java层的消耗。同时,在加载图片时,图片Config参数也可以有效减少内存的消耗。比如图片存储的位数及
options.inSampleSize
图片的尺寸等。

     平时遇到的小小问题,总结一下,就写这么多吧。




您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP