Android在加载大背景图或者大量图片时,经常导致内存溢出(Out of Memory  Error),本文根据我处理这些问题的经历及其它开发者的经验,整理解决方案如下(部分代码及文字出处无法考证):
 方案一、读取图片时注意方法的调用,适当压缩  尽量不要使用setImageBitmapsetImageResourceBitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的  source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。

InputStream is = this.getResources().openRawResource(R.drawable.pic1);

BitmapFactory.Options options = new  BitmapFactory.Options();

options.inJustDecodeBounds =  false;

options.inSampleSize =  10;   // width,hight设为原来的十分一

Bitmap btp =  BitmapFactory.decodeStream(is, null,  options);

如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常。

/**

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

*  @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);

}

另外,decodeStream直接拿图片来读取字节码,  不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,  否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
方案二、在适当的时候及时回收图片占用的内存  通常Activity或者Fragment在onStop/onDestroy时候就可以释放图片资源:

 if(imageView !=  null &&  imageView.getDrawable() != null){

Bitmap oldBitmap =  ((BitmapDrawable) imageView.getDrawable()).getBitmap();

imageView.setImageDrawable(null);

if(oldBitmap !=  null){

oldBitmap.recycle();

oldBitmap =  null;

}

}

//  Other code.

System.gc();

在释放资源时,需要注意释放的Bitmap或者相关的Drawable是否有被其它类引用。如果正常的调用,可以通过Bitmap.isRecycled()方法来判断是否有被标记回收;而如果是被UI线程的界面相关代码使用,就需要特别小心避免回收有可能被使用的资源,不然有可能抛出系统异常: E/AndroidRuntime: java.lang.IllegalArgumentException: Cannot draw recycled  bitmaps 并且该异常无法有效捕捉并处理。
方案三、不必要的时候避免图片的完整加载 只需要知道图片大小的情形下,可以不完整加载图片到内存。 在使用BitmapFactory压缩图片的时候,BitmapFactory.Options设置inJustDecodeBounds为true后,再使用decodeFile()等方法,可以在不分配空间状态下计算出图片的大小。示例:

BitmapFactory.Options opts =  new  BitmapFactory.Options();

//  设置inJustDecodeBounds为false

opts.inJustDecodeBounds = false;

//  使用decodeFile方法得到图片的宽和高

BitmapFactory.decodeFile(path,  opts);

//  打印出图片的宽和高

Log.d("example", opts.outWidth + "," + opts.outHeight);

(ps:原理其实就是通过图片的头部信息读取图片的基本信息)
方案四、优化Dalvik虚拟机的堆内存分配  堆(HEAP)是VM中占用内存最多的部分,通常是动态分配的。堆的大小不是一成不变的,通常有一个分配机制来控制它的大小。比如初始的HEAP是4M大,当4M的空间被占用超过75%的时候,重新分配堆为8M大;当8M被占用超过75%,分配堆为16M大。倒过来,当16M的堆利用不足30%的时候,缩减它的大小为8M大。重新设置堆的大小,尤其是压缩,一般会涉及到内存的拷贝,所以变更堆的大小对效率有不良影响。 Heap  Utilization是堆的利用率。当实际的利用率偏离这个百分比的时候,虚拟机会在GC的时候调整堆内存大小,让实际占用率向个百分比靠拢。使用  dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。

 private final static float  TARGET_HEAP_UTILIZATION = 0.75f;

//  在程序onCreate时就可以调用

VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);

方案五、自定义堆(Heap)内存大小  对于一些Android项目,影响性能瓶颈的主要是Android自己内存管理机制问题,目前手机厂商对RAM都比较吝啬,对于软件的流畅性来说RAM对性能的影响十分敏感,除了优化Dalvik虚拟机的堆内存分配外,我们还可以强制定义自己软件的对内存大小,我们使用Dalvik提供的  dalvik.system.VMRuntime类来设置最小堆内存为例:

 private final static int  CWJ_HEAP_SIZE = 6 * 1024 * 1024  ;

VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);  //  设置最小heap内存为6MB大小。

但是上面方法还是存在问题,函数setMinimumHeapSize其实只是改变了堆的下限值,它可以防止过于频繁的堆内存分配,当设置最小堆内存大小超过上限值(Max Heap  Size)时仍然采用堆的上限值,对于内存不足没什么作用。  
最后介绍一下图片占用进程的内存算法。android中处理图片的基础类是Bitmap,顾名思义,就是位图。占用内存的算法如:图片的width*height*Config。 如果Config设置为ARGB_8888,那么上面的Config就是4。一张480*320的图片占用的内存就是480*320*4  byte。 在默认情况下android进程的内存占用量为16M,因为Bitmap他除了java中持有数据外,底层C++的  skia图形库还会持有一个SKBitmap对象,因此一般图片占用内存推荐大小应该不超过8M。这个可以调整,编译源代码时可以设置参数。

参考资料:http://www.tuicool.com/articles/yemM7zf

方案六:在Manifest.xml文件里面的<application  里面添加Android:largeHeap="true"

简单粗暴。这种方法允许应用需要耗费手机很多的内存空间,但却是最快捷的解决办法

Android加载图片导致内存溢出(Out of Memory异常)相关推荐

  1. 图片--Android加载图片导致内存溢出(Out of Memory异常)

    Android在加载大背景图或者大量图片时,经常导致内存溢出(Out of Memory  Error),本文根据我处理这些问题的经历及其它开发者的经验,整理解决方案如下(部分代码及文字出处无法考证) ...

  2. 在Recyclerview使用GlideAPP加载大量图片导致内存溢出(oom)

    网络上有很多解决的办法,但是都是在清理磁盘缓存和内存上做,并不能及时释放内存. 1.可以在每次请求数据和加载数据后调用 /** * 清除内存缓存. */public static void clear ...

  3. Android加载图片内存溢出问题解决方法

    这篇文章主要介绍了Android加载图片内存溢出问题解决方法,本文讲解使用BitmapFactory.Options解决内存溢出问题,需要的朋友可以参考下 1. 在Android软件开发过程中,图片处 ...

  4. canny算法的实现(android加载图片,数组写入文件换行)

    Canny边缘检测首先要对图像进行高斯去噪,前面讲到了高斯去噪处理,这里从对图像灰度进行微分运算讲起吧.微分运算常用的方法是利用模板算子,把模板中心对应到图像的每一个像素位置,然后按照模板对应的公式对 ...

  5. Android加载图片OOM错误解决方式

    前几天做项目的时候,甲方要求是PAD (SAMSUNG P600 10.1寸 2560*1600)的PAD上显示高分辨率的大图片. SQLITE採用BOLD方式存储图片,这个存取过程就不说了哈,网上一 ...

  6. 专为Android加载图片Fresco:详细图解SimpleDraweeView加载图片基础

    Fresco简单的使用-SimpleDraweeView 百学须先立志-学前须知: 在我们平时加载图片(不管是下载还是加载本地图片-..)的时候,我们经常会遇到这样一个需求,那就是当图片正在加载时应该 ...

  7. android 加载图片并在上面画图

    像Ps上的应用一样,我们加载一个图片然后在上面增加各种我们需要的挂件,文字效果等.我们今天完成一个简单的Demo package com.example.fingerdraw;import java. ...

  8. android 加载so 与内存的关系,Android动态调试so之dump内存数据

    1.配置环境 一台已root手机 IDA pro6.6 Android SDK 准备工作: 1.1把Android SDK添加到环境变量中 1.2把已root手机的系统中关键so拖到本地,必要时可以静 ...

  9. android 加载图片黑屏,Android 中启动页黑屏及白屏的解决方式

    启动页黑屏或白屏的原因是,当Activity启动的时候不能马上加载layout. 而黑屏或者白屏是你的theme主题的默认样式,当layout没加载出来就显示黑屏或者白屏. 1.windowBackg ...

最新文章

  1. 大陆唯一7nm光刻机被抵押!武汉千亿投资、台积电大牛掌舵的芯片项目官宣停摆...
  2. N - Find a way HDU - 2612
  3. 3.关于QT中的MainWindow窗口,MenuBar,ToolBar,QuickTip等方面的知识点
  4. 真实的linux系统是怎样的,只使用Linux系统是怎样一种体验?_科技数码通
  5. 邀请函|WorkShop报名通道开启,来就送礼!
  6. Visual Studio 2019 使用 Live Share
  7. CoreAnimation编程指南(一)概念
  8. for循环false 终止 python_python3.5.1给用户3次无效的尝试,然后终止pgm(Simple FOR循环)...
  9. python引入导入自定义模块和外部文件
  10. windows系统磁盘使用记录(自用)
  11. Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 10.x
  12. CDH5部署三部曲之二:部署和设置,高薪程序员必会
  13. 类加载过程(时机)略解
  14. ofo给还在路上垂死挣扎的战友们留下什么启示?
  15. Camera_Hal3_User_Manual
  16. VS2013 安装及问题解决
  17. Chapter 6. MATLAB数值计算基础
  18. STM32实战总结:HAL之数码管
  19. 华裔天才数学家-陶哲轩
  20. android 签名文件与sha1获取

热门文章

  1. 奔驰809android auto,奔驰E Android Auto+AA Mirro技术作业
  2. pcie台式网卡无法开热点
  3. 收藏了!3D建模软件大全,想入门3D建模的小伙伴一定不要错过
  4. 1.23山师训练赛补题
  5. SQL语句增删改查公司-员工3表典型案例
  6. 金蝶KSQL 增加字段/改变字段长度
  7. LLDB breakpoint syntax
  8. 支持响应式手机端jQuery图片轮播插件unslider
  9. Android 开发摆脱数据线 - Android studio 无线调试App
  10. 单页面SPA(如react,vue)网站的服务器渲染SSR之SEO大杀器rendertron(超详细配置+避坑)