• setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多的内存。
  • 改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的source
  • decodeStream最大的好处在于其直接调用JNI  的nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间
  • 如果在读取时加上图片的Config参数,可以更有效减少加载的内存,从而更有效避免out of memory的异常
  • 另外,decodeStream直接拿图片来读取字节码,不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要配置相应大小的图片资源
  • 默认情况下android进程的内存占用量为16M,因为bitmap他除了java中持有数据外,底层C++的skia图形库还会持有一个SKBitmap对象,因此一般图片占用内存推荐大小应该不超过8M


1、BitmapFactory.Options

  • inPreferredConfig 指定decode到内存中,手机中所采用的编码,可选值定义在Bitmap.Config中。缺省值是ARGB_8888。可以使ALPHA_8、ARGB_444、ARGB_8888、RGB_565                                               bitmap占用内存的算法如下:图片的width*height*Config                                                                                                                                                                                                                                             如果config设置为ARGB_8888,那么上面的Config为4,也就是4个字节的意思。一张480*320的图片占用的内存就是480*320*4byte。
  • inJustDecodeBounds 如果设置为true,并不会把图像的数据完全解码,亦即decodeXyz()返回值为null,但是Options的outAbc中解出了图像的基本信息。
  • inSampleSize 设置decode时的缩放比例。
  • inPurgeable设为true的话表示使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间在系统内存不足时可以被回收,在应用需要再次访问bitmap的Pixel时,系统会再次条用BitmapFactory decoder重新生成Bitmap的Pixel数组,为了能够重新解码图像,bitmap要能够访问存储bitmap的原始数据。在inPugeable为false时表示创建bitmap的pixel内存空间不能被回收,这样bitmapfactory在不停decodeByteArray创建新的Bitmap对象,不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,200个bitmap足以使大部分的设备出现OutOfMemory错误。当inPurgeable设为true时,系统中内存不足时,可以回收部分bitmap占据的内存空间,这时一般不会出现OutOfMemory错误
  • inInputShareable是否深拷贝



2、以最省内存的方式读取本地资源的图片 

  1. BitmapFactory.Options opt = new BitmapFactory.Options();
  2. opt.inPreferredConfig = Bitmap.Config.RGB_565;
  3. opt.inPurgeable = true;
  4. opt.inInputShareable = true;
  5. //获取资源图片
  6. InputStream is = context.getResources().openRawResource(resId);
  7. BitmapFactory.decodeStream(is,null,opt);


3、最近解决bitmap加载时out of memory的心得


游戏在加载背景图片
       要么挂在
BitmapFactory. decodeStream
assets
 .open(path));
    要么挂在
surface 
= Bitmap.createBitmap (
surface 
, 0, 0,


                
surface
 .getWidth(), 
surface 
.getHeight(), matrix, 
true
);
第一次尝试:
看到图片是png格式的,将图片转为jpg。图片大小减少了不少。不过没多大效果。  
        原因:虽然改为jpg,加载时存储的方式会默认为ARGB_565,本来是png为ARGB_8888,占用内存会减少一半。不过开销还是很大,用createBitmap放大时,改方法是java层的实现,效率太差。

第二次尝试:想到cocos2d-x的瓦片地图,所以将背景图片分割为9份(自己用ps切),有些效果,不会每次切换场景都会挂,但是很多的征战地图,没全部切,所以当进入没切的场景时,还是会挂。

                
   
原因:没有找到问题的源头,变小图了,加载时开销的内存确实减少不少。不过太多场景都去切不太实际,这样程序改变很大。可能会出现bug的风险。

第三次尝试:配置BitmapFactory.Config的属性,使用(2)中的方式读取图片,省去createBitmap去放大图片,使用两套资源,在这些屏幕上用大图。成功解决问题。
             原因:都用了BitmapFactory.decodeStream方法读取图片,改方法直接使用native方法,用c++实现。效率果然是高。虽然当时还不知道这个原因。今天总结的时候通过源代码才理解。

android bitmap out of memory总结、心得的更多相关文章

  1. [翻译]开发文档:android Bitmap的高效使用

    内容概述 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently",包括大尺寸Bitmap的高效加载,图片的异步加载和数据缓存 ...

  2. Android Bitmap 载入与像素操作

    Android Bitmap 载入与像素操作 一:载入与像素读写 在Android SDK中,图像的像素读写能够通过getPixel与setPixel两个Bitmap的API实现. Bitmap AP ...

  3. Android Bitmap变迁与原理解析(4.x-8.x)

    App开发不可避免的要和图片打交道,由于其占用内存非常大,管理不当很容易导致内存不足,最后OOM,图片的背后其实是Bitmap,它是Android中最能吃内存的对象之一,也是很多OOM的元凶,不过,在 ...

  4. Android Bitmap缓存介绍

    转载自http://blog.csdn.net/linghu_java/article/details/8595717 Android中加载一个Bitmap(位图)到你的UI界面是非常简单的,但是如果 ...

  5. Android Bitmap 和 ByteArray的互相转换

    Android Bitmap 和 ByteArray的互相转换 移动平台图像处理,需要将图像传给native处理,如何传递?将bitmap转换成一个 byte[] 方便传递也方便cpp代码直接处理图像 ...

  6. Android——BitMap(位图)相关知识总结贴

    Android中文API(136) —— Bitmap http://www.apkbus.com/android-54644-1-1.html Android 4.0 r1 API—Bitmap(S ...

  7. Android bitmap高效显示和优化

    第一部分:Bitmap高效显示 应用场景:有时候我们想在界面上显示一个网络图片或者显示一张本地的图片,但是图片本身是很大的有几兆,但是显示的位置很小或者说我们可以用更小的图片来满足这样的需求,如果把整 ...

  8. Android Bitmap 全面解析(四)图片处理效果对比 ...

    对比对象: UIL Volley 官方教程中的方法(此系列教程一里介绍的,ImageLoader的处理方法和官方的差不多) -------------------------------------- ...

  9. 36、Android Bitmap 全面解析

    Android Bitmap 全面解析(一)加载大尺寸图片 http://www.eoeandroid.com/thread-331669-1-1.html Android Bitmap 全面解析(二 ...

随机推荐

  1. 开发一个iOS应用没有那么容易

    导读:这是来自新加坡的 iOS 开发者 Kent Nguyen 发表在1月底的一篇博文.这篇吐槽文在 iOS 开发圈子里流传甚广,从原文150多个评论就可见一斑,现翻译如下. 让我们开门见山吧:做一个 ...

  2. 还原没有日志文件的SQL数据库

    1.执行命令示例: EXEC sys.sp_attach_db @dbname = 'AdventrueWorks2012_Data',     @filename1 = N'C:\Program F ...

  3. POJ 3801 有上下界最小流

    1: /** 2: POJ 3801 有上下界的最小流 3: 4: 1.对supersrc到supersink 求一次最大流,记为f1.(在有源汇的情况下,先使整个网络趋向必须边尽量满足的情况) 5: ...

  4. Ubuntu实用快捷键

    ALT + TAB: 切换程序窗口Win+w: 显示所有的工作空间,可轻松进行切换 ===== Terminal终端 ===== CTRL + ALT + T: 打开终端 TAB: 自动补全命令或文件 ...

  5. js 正则 数值验证

    function checkTextDataForNORMAL(strValue) { // 特殊字符验证格式 var regTextChar = /([\*"\'<>\/])+ ...

  6. [原创汉化]linux前端神器 WebStorm8 汉化

    只汉化了linux版本 因为linux的工具没win多 不过汉化应该都通用的,自行尝试下. 汉化的不是很完全.有时间放出完全版本来.汉化是个体力活 转载随易,汉化不易,且转且注明 截图: http:/ ...

  7. Java多线程——<六>更方便的线程

    一.概述 标题很抽象,什么叫更方便?更是相比谁来说的呢? 原来,我们定义任务,都是实现自Runnable或者Callable接口,但是这样必然需要你将新定义的任务附着给线程,然后再调用线程启动.在不考 ...

  8. ubuntu下opencv2.4.9安装测试

    ubuntu下opencv2.4.9安装测试 whowhoha@outlook.com 一.依赖包安装 1.  build-essential 软件包 sudo apt-get install bui ...

  9. 01-03-03【Nhibernate (版本3.3.1.4000) 出入江湖】cascade的测试

    相关文章: http://www.cnblogs.com/amboyna/archive/2008/02/18/1072260.html注意上面是hibernate,不是Nhibernate,这解释是 ...

  10. Web App之一

    JSP/HTML/CSS---------View(不包含任何的数据,只作为基本的layout) JS------------------------Data(update JSP/HTML)