关于Android加载图片OOM的思考

简介: 大家都知道,使用Android加载图片时,一般来说加载几个图片都容易OOM,但是Android手机的相册似乎没有这个问题。 思索了很久没有找到办法,和一个哥们讨论次问题时他给出个解决办法: (下面的文字转自:http://blog.sina.com.cn/s/blog_7139b0e30100xklb.html,所以本博文属于转载) 写Android代码也有那么三四个月的时间了,也一直都是菜鸟,很多东西都只是拿来就用,也没有想太多的细节问题。
大家都知道,使用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));
   运行结果是:
    Android加载大图片内存溢出的问题总结

    
    再来看看使用 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));

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

明天去单位实验一下看看,如果可以告诉大家结构。
目录
相关文章
|
7月前
|
Java 开发工具 Maven
Android 编译 gradle 内存 OOM 解决之路(二)
Android 编译 gradle 内存 OOM 解决之路
|
7月前
|
Java Android开发
Android 编译 gradle 内存 OOM 解决之路(一)
Android 编译 gradle 内存 OOM 解决之路
|
前端开发 Java Linux
内存泄露,OOM,ANR ,Devik 进程,Framework原理,Activity 生成一个 view,Android 中的动画,SurfaceView和V
内存泄露,OOM,ANR ,Devik 进程,Framework原理,Activity 生成一个 view,Android 中的动画,SurfaceView和V
196 0
|
Java Linux Android开发
转 - Android下一次OOM调试过程
线程数超限,即proc/pid/status中记录的线程数(threads项)突破/proc/sys/kernel/threads-max中规定的最大线程数。
96 0
|
XML 缓存 数据库
Android Glide加载图片、网络监听、设置资源监听
Android Glide加载图片、网络监听、设置资源监听
624 0
Android Glide加载图片、网络监听、设置资源监听
|
Android开发
Android RV通过Glide加载图片闪一下
Android RV通过Glide加载图片闪一下
114 0
Android RV通过Glide加载图片闪一下
|
算法 Java Android开发
Android性能优化 | 帧动画OOM?优化帧动画之SurfaceView逐帧解析
应用 SurfaceView 逐帧绘制帧动画配合 Bitmap 复用。和原生帧动画的内存压力及卡顿说再见!
833 0
|
缓存 Android开发
Android笔记:使用Glide加载图片刷新时会闪烁
Android笔记:使用Glide加载图片刷新时会闪烁
1093 0
|
监控 Java Linux
Android进阶性能调优;不可思议的OOM
前言; 本文发现了一类OOM(OutOfMemoryError),这类OOM的特点是崩溃时java堆内存和设备物理内存都充足,下文将带你探索并解释这类OOM抛出的原因。
1916 0
|
Android开发 Java
Android项目实战(十二):解决OOM的一种偷懒又有效的办法
原文:Android项目实战(十二):解决OOM的一种偷懒又有效的办法 在程序的manifest文件的application节点加入android:largeHeap=“true” 即可。 对,只需要一句话! 那么这行代码的意思是什么呢? 简单的说就是使该APP获取最大可分配的内存,以便解决OOM问题、 但是、OOM问题出现的原因总得来说有两点: 1、某个手机的内存真的很少 2、代码问题,比如没有处理好Bitmap图片的大小 可以说,出现OOM的情况基本都是第二种情况,那么就需要修改代码,看看哪里没有处理好。
1023 0