Android载入图片OOM错误解决方案

前几天做项目的时候,甲方要求是PAD (SAMSUNG P600 10.1寸 2560*1600)的PAD上显示高分辨率的大图片。

SQLITE采用BOLD方式存储图片,这个存取过程就不说了哈,网上一大堆。

但是在载入/读取/显示图片的时候会报OOM错误,上网查了很多解决方案还绕了很多弯路,最后还是找到了原因所在,下面从几个方面来解释一下OOM问题的解决方案。

(谢谢周同学的“尺寸”提醒,不然我可能一辈子都要蒙在鼓里)

1.Android APP内存

做一个APP开发的时候,还是不要想着去扩大Android系统赋予的内存上限了,部分老机型老系统16M,大部分都是24M了。

一些大型游戏用dalvik.system.VMRuntime来干涉GC过程(这个类我还没有学过。。。刚听说不久)。

据说用NDK开发时候,C可以动态申请多余的内存空间,但是我没用过NDK,今后也不打算用了(个人原因)。

2.图片文件大小

甲方给了一大堆文件大小不一的图片,在载入数据库->读取出来->显示出来的这个过程中,出现了很多OOM,分为:

a.载入图片时使用ByteArrayStream创建流,size为Height * Width * 4,OOM;

b.读取图片时候OOM,同上;

c.显示图片时候OOM,decodeResource函数报错,OOM;

开始时候以为是文件大小问题,后来发现有些2M的图片都能显示,但是某些1M的图片确报错,所以在一定范围内,可以证明,图片OOM问题与文件大小无关。

3.图片尺寸(分辨率)

调查这些能显示的图片和不能显示的图片的不同,发现长宽差距很大,那些能成功显示的图片为1005*1500大小,而其他图片都是3000*5000以上。

我用PAINT(一款适合小白的图像处理软件,虽然不如PS但是功能已经非常强大了,最新版需要安装NET 4.5)压缩了图片大小,压缩到1005*1500,显示成功。

4.函数调用

阅读了这位大神的博客:

http://blog.csdn.net/huangbiao86/article/details/8072128

摘取其中最精华的部分吧:

尽量不要使用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之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源, 否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。

看来读底层源码还是很有用的,setImageBitmap 和 setImageResource 和 decodeResource在执行过程中还是调用了createBitmap来创建一个新的bitmap,创建bitmap会加剧内存消耗,所以不推荐使用了,应该使用decodeStream方法。

图片的压缩过程也可以设置一个合适的百分比来控制大小。

多张图片的使用中,请注意流的flush与close(我没有及时flush和close的时候也运行正确了,这个有待研究一下,但是为了保证一个良好的习惯还是注意下吧)。

5.关于options方法

网上还有很多文章用BitmapFactory.Options来作为decodeStream时候的一个参数,这个我暂时没有具体实验过,哪位朋友实验过了可以回复交流哈

时间: 2024-10-23 01:35:22

Android载入图片OOM错误解决方案的相关文章

android jdbc 数据库连接错误解决方案

今天用Eclipse突然在控制台出现如下错误,没有办法运行程序: [plain] view plaincopyprint? Invalid layout of java.lang.String at value A fatal error has been detected by the Java Runtime Environment: Internal Error (javaClasses.cpp:129), pid=15238, tid=140306591237888 fatal erro

Android OOM异常解决方案

一,什么是OOM异常: OOM(out of Memory)即内存溢出异常,也就是说内存占有量超过了VM所分配的最大,导致应用程序异常终止: 二,为什么会产生OOM异常呢? OOM异常是Android中经常遇到的一个问题,程序员稍微不注意可能就导致其产生.通常OOM都发生在需要用到大量内存的情况下,因为Android的每一个应用都是一个Davlik虚拟机,该虚拟机的默认堆内存只有16M,远远无法跟我们的PC机比较,因此和容易导致OOM(Out Of Memory)异常的产生.导致这样的异常主要有

Android OOM的解决方案

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source, decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsse

Git在开发android系统时常用的技巧及常见错误解决方案

Git常用的技巧及常见错误解决方案 项目管理工作 repo 常用命令 ==目标== 了解repo工作原理及常用的repo命令 Git 日常使用的命令,常见问题及解决方案 ==关键词== Repo , Git ==工作指南== == <big>Repo</big> == Android代码其实是由若干个git 工作组织在一起的,repo 是一个便于整体管理这些项目的脚本. 拉代码时需要用到几个步骤,分别对几个步骤进行阐述一下,网上有很多repo 的使用方法,但是对其工作原理描述的并不

Android Studio上Session &#39;app&#39;: Error Installing APK错误解决方案

我在使用Android Studio的时候,使用自己的魅族(M5 Note)真机调试,运行不成功,提示下面图片中的错误(Session 'app':Error Installing APK). 再经过测试过好几种网上的方法之后,特记录如下,望以后大家少走弯路,希望可以帮助到大家. 可能不同的人使用到的方法都会是下面的不同的方法: 1)连接手机之后,会有显示手机的SDK型号以及API的版本,显示我自己的是魅族M5 Note(Android 6,API23),在我的手机上安装不上,刚开始有人说魅族手

Android开发各类常见错误解决方案

本文属于个人平时项目开发过程遇到的一些问题,记录下来并总结解决方案,希望能帮到大家解决问题,有些问题的解决方案是在StackoverFlow上找到的,建议大家遇到问题多去上面找,基本上都能找到解决方案的. (1)将Eclipse项目导入到Android studio 中 很多点9图出现问题解决方法:在build.gradle里添加以下两句: aaptOptions.cruncherEnabled = false aaptOptions.useNewCruncher = false 用来关闭And

android系统AES解密服务器加密数据错误解决方案

之前的做了一个外包项目,里边有一些敏感的信息需要AES加密,但是同样的代码在服务器就可以加密解密,在android系统中就解密失败,会出现pad block corrupted错误,下面给出解决方案, 亲测无问题! AES.java public class AES { public static final String VIPARA = "0123456789abcdef"; public static final String bm = "UTF-8"; pu

mac 无法连接android手机进行调试 解决方案

第一步: 查看usb设备信息 在 终端输入:system_profiler SPUSBDataType     可以查看连接的usb设备的信息 比如我的usb信息如下(部分内容): Android: Product ID: 0x2769              Vendor ID: 0x22d9              Version: 2.31              Serial Number: 6e5d48a4              Speed: Up to 480 Mb/sec

Android处理图片OOM的若干方法小结 (推荐)

众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定).因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片.音频文件.视频文件等多媒体资源:由于Android系统对音频.视频等资源做了边解析便播放的处理,使用时并不会把整个文件加载到内存中,一般不会出现内存溢出(以下简称OOM)的错误,因此它们的内存消耗问题暂不在本文的讨论范围.本文重点讨论的是图片的内存消耗问题,如果你要开发的是一款图片浏览器应用,例如像And