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

今天做项目,发现需要显示一张超大图片,处理过后,还有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中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

时间: 2024-10-01 16:37:59

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

Android开发实现ImageView加载摄像头拍摄的大图功能

本文实例讲述了Android开发实现ImageView加载摄像头拍摄的大图功能.分享给大家供大家参考,具体如下: 这个方法是从官方demo中摘录的,在此记录学习. 权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera2" android:re

torch7中如何加载bmp格式的图片?

问题描述 torch7中如何加载bmp格式的图片? 因为需要用到特定的数据集,数据集里都是bmp格式的图片.torch中通过image.load()不能加载bmp格式的图片,但是由于数据集太大,不方便做批量格式转换,请问有其他的可选方案吗? 解决方案 转载博客地址:http://www.cnblogs.com/landmark/ 到现在为止我们只创建了一个窗口,其他什么都没干,这次我们将在窗口里显示图片,这是视频子系统最常用的功能,显示图片.SDL视频子系统只能加载bmp格式的位图.调用函数是S

java中页面加载的时候如何让指定的按钮获得焦点定位

问题描述 帮忙看看下面的代码出现的问题<bodyonload="initFocus()"><formaction="imageInform.do?param=doFindByPicSort"method="post"><table><tr><td><ahref="history.do?param=doFindHistoryByCaCard"><div

解析iOS应用的UI开发中懒加载和xib的简单使用方法_IOS

懒加载 1.懒加载基本 懒加载--也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,写的是其get方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化 2.使用懒加载的好处: (1)不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 (2)每个控件的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 3.代码示例 复制代码 代码如下: // //  YYViewController.m //

Android利用Volley异步加载数据(JSON和图片)完整示例

MainActivity如下: package cc.testvolley; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v4.util.LruCache; import android.widge

jquery实现在页面加载完毕后获取图片高度或宽度_jquery

日前,本技术屌丝又遇到了一个很有意思的问题,应项目要求,需要在页面加载完毕之后获取图片的高度,以此来调整图片上面的覆盖层相对于图片顶端的位置. 但在jquery(function(){ /*XXXXXX*/});里面写了之后发现不是很理想,因为当jquery准备就绪的时候,此时图片绝大部分情况下都没加载完毕,这可急坏了本屌丝~~~T~T 本屌丝就想啊,要是jquery有个跟js的onload()的方法多好啊,擦~真是天上掉下个大狗屎,恰巧砸到本屌丝~~在网上搜了下,还真有这么个方法,写法如下:

app开发-WeX5中打完Android包后再手机上运行,静态页面加载出来了,但是不能发请求

问题描述 WeX5中打完Android包后再手机上运行,静态页面加载出来了,但是不能发请求 打包时设置的首页显示出来了,但是点击首页上的按钮,没有反应,没有执行js中的点击方法 解决方案 没用过 刚刚百度了下 才知道有WeX5这东西

Android开发中如何解决加载大图片时内存溢出的问题

Android开发中如何解决加载大图片时内存溢出的问题    在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给大家.   尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过Bitmap

Android 开发中fragment预加载问题

我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源.这样的结果,我们当然不会满意.那么,能不能做到当切换到这个fragment的时候,它才去初始化呢? 答案就在Fragment里的setUserVisibleHint这个方法里.请看关于Fragment里这个方法的API文档(国内镜像地址:ht