文档章节

Android开发中 页面加载一张超大图片(561kb)时出现OOM

今日竹石
 今日竹石
发布于 2014/03/18 13:34
字数 461
阅读 40
收藏 0

    今天做项目,发现需要显示一张超大图片,处理过后,还有561Kb

     加载的时候,就crash --- OOM

     shortMsg:java.lang.OutOfMemoryError

     longMsg:java.lang.OutOfMemoryError: bitmap size exceeds VM budget

     stackTrace:java.lang.OutOfMemoryError: bitmap size exceeds VM budget
     at android.graphics.Bitmap.nativeCreate(Native Method)
     at android.graphics.Bitmap.createBitmap(Bitmap.java:477)
     at android.graphics.Bitmap.createBitmap(Bitmap.java:444)
     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349)
     at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:512)
     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:487)
     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)

     

      代码如下:

      detailView=(ImageView)findViewById(R.id.detailView);

      detailView.setBackgroundResource(R.drawable.more_info);//this line will lead to OOM 

       换成这种:

      detailView.setImageResource(R.drawable.more_info); //也同样会OOM

       

       后来找到了solution:

        /**
          * 以最省内存的方式读取本地资源的图片
          * @param context
          *@param resId
          * @return
          */  
    public static Bitmap readBitMap(Context context, int resId){  
        BitmapFactory.Options opt = new BitmapFactory.Options();  
        opt.inPreferredConfig = Bitmap.Config.RGB_565;   
       opt.inPurgeable = true;  
       opt.inInputShareable = true;  
          //获取资源图片  
       InputStream is = context.getResources().openRawResource(resId);  
           return BitmapFactory.decodeStream(is,null,opt);  
    }
     

    取得bitmap之后,再 detailView.setImageBitmap(pdfImage); 就ok了!      


     那是为什么,会导致oom呢:

         原来当使用像 imageView.setBackgroundResource,imageView.setImageResource, 或者 BitmapFactory.decodeResource  这样的方法来设置一张大图片的时候,

         这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。

         因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常。

        另外,需要特别注意: 

         decodeStream是直接读取图片资料的字节码了, 不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。



© 著作权归作者所有

今日竹石
粉丝 41
博文 227
码字总数 181312
作品 0
朝阳
程序员
私信 提问
Android超大图片不缩小要怎样处理。

android里面有个类似指南针的程序要做,但要加载一幅超大图片,3000x3000,不能让他失真,要有放大和缩小功能,最大能放到和原图一样的大小,最小是刚刚能现在满屏幕,而且要根据方向图片不断...

tukiyuki
2014/02/26
559
1
Android高效加载大图、多图解决方案,有效避免程序OOM

高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状、不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小。比如说系统图片库里展...

工作日
2013/08/26
236
1
Android Flutter 内存机制初探

阿里妹导读:闲鱼技术团队一直在探索如何使用Flutter来统一移动App开发。移动设备上的资源有限,内存使用成了日常开发中的常见问题。那么,Flutter是如何使用内存,又会对Native App的内存带...

b0q8cpra539hafs7
2018/05/23
0
0
Android Flutter实践内存初探

闲鱼技术-匠修 我们想使用Flutter来统一移动App开发并做了一些实践。移动设备上的资源有限,通常内存使用都是一个我们日常开发中十分关注的问题。那么,Flutter是如何使用内存,又会对Nativ...

迷你芊宝宝
2018/07/02
31
0
KJFrameForAndroid框架学习----高效加载Bitmap

欢迎各位加入我的Android开发群[257053751] KJFrameForAndroid框架项目地址:https://github.com/kymjs/KJFrameForAndroid 我们在写Android程序的时候,肯定会用到很多图片。那么对于图片的压...

kymjs张涛
2014/07/17
3.4K
14

没有更多内容

加载失败,请刷新页面

加载更多

DevOps是如何实现效率的提升?

随着企业业务对软件系统日益依赖,IT管理与研发模式也随之对“敏态”模式产生了需求,也就是今天时常提起的DevOps。提升效率,是DevOps实践的核心内容之一。就让我们来一起从软件生命周期的业...

嘉为科技
19分钟前
2
0
总结:linux目录之proc

我们系统大部分的基础数据采集,其实就是读取proc目录下的文件,并解析获取数据的过程。 1、如cpu利用率:直接cat /proc/cpuinfo命令,然后获取输出内容,并解析里面的数据,如cpu核数等; ...

浮躁的码农
21分钟前
2
0
比原Bapp红包应用

喜迎国庆期间,比原链在自己的移动端钱包Bycoin(下载地址)和google插件钱byone中推出了红包应用,在国庆期间深受大家好评。 那我们今天就来大概介绍一下比原红包,以及基于比原链开发dapp应用...

比原链Bytom
22分钟前
2
0
Linux中没有rc.local文件的解决方法

Linux中没有rc.local文件的解决方法是什么呢?这应该是很多工程师比较头疼的问题,下面就给大家例举几个解决办法。 比较新的Linux发行版已经没有rc.local文件了。因为已经将其服务化了。 解决...

xiangyunyan
23分钟前
2
0
数据中台在阿里巴巴集团内部的实践情况

作者:品鉴 数据中台门在阿里巴巴集团干什么的,由哪个部门掌管?数据中台在阿里巴巴的主要作用是什么呢?外面吹嘘这么神秘的数据中台在阿里实践的如何呢?今天小编正好要采访数据技术及产品...

阿里云官方博客
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部