android加载大量图片内存溢出bitmap size exceeds VM budget的解决办法。

简介:

方法一:

在从网络或本地加载图片的时候,只加载缩略图。

/**
  * 按照路径加载图片
  * @param path 图片资源的存放路径
  * @param scalSize 缩小的倍数
  * @return
  */
 public static Bitmap loadResBitmap(String path, int scalSize) {
     BitmapFactory.Options options = new BitmapFactory.Options();
     options.inJustDecodeBounds = false;
     options.inSampleSize = scalSize;   
     Bitmap bmp = BitmapFactory.decodeFile(path, options);
  return bmp;
 }

这个方法的确能够少占用不少内存,可是它的致命的缺点就是,因为加载的是缩略图,所以图片失真比较严重,对于对图片质量要求很高的应用,可以采用下面的方法。

方法二:

运用JAVA的软引用,进行图片缓存,将经常需要加载的图片,存放在缓存里,避免反复加载。

关于软引用(SoftReference)的详细说明,请参看http://blog.csdn.net/helixiuqqq/article/details/6610199。下面是我写的一个图片缓存的工具类。


/**
 *
 * @author larson.liu
 * 该类用于图片缓存,防止内存溢出
 */
public class BitmapCache {
 static private BitmapCache cache;
 /** 用于Chche内容的存储*/
 private Hashtable<Integer, BtimapRef> bitmapRefs;
 /** 垃圾Reference的队列(所引用的对象已经被回收,则将该引用存入队列中)*/
 private ReferenceQueue<Bitmap> q;

 /**
  * 继承SoftReference,使得每一个实例都具有可识别的标识。
  */
 private class BtimapRef extends SoftReference<Bitmap> {
  private Integer _key = 0;

  public BtimapRef(Bitmap bmp, ReferenceQueue<Bitmap> q, int key) {
   super(bmp, q);
   _key = key;
  }
 }

 private BitmapCache() {
  bitmapRefs = new Hashtable<Integer, BtimapRef>();
  q = new ReferenceQueue<Bitmap>();

 }

 /**
  * 取得缓存器实例
  */
 public static BitmapCache getInstance() {
  if (cache == null) {
   cache = new BitmapCache();
  }
  return cache;

 }

 /**
  * 以软引用的方式对一个Bitmap对象的实例进行引用并保存该引用
  */
 private void addCacheBitmap(Bitmap bmp, Integer key) {
  cleanCache();// 清除垃圾引用
  BtimapRef ref = new BtimapRef(bmp, q, key);
  bitmapRefs.put(key, ref);
 }

 /**
  * 依据所指定的drawable下的图片资源ID号(可以根据自己的需要从网络或本地path下获取),重新获取相应Bitmap对象的实例
  */
 public Bitmap getBitmap(int resId, Context context) {
  Bitmap bmp = null;
  // 缓存中是否有该Bitmap实例的软引用,如果有,从软引用中取得。
  if (bitmapRefs.containsKey(resId)) {
   BtimapRef ref = (BtimapRef) bitmapRefs.get(resId);
   bmp = (Bitmap) ref.get();
  }
  // 如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,
  // 并保存对这个新建实例的软引用
  if (bmp == null) {
   bmp = BitmapFactory.decodeResource(context.getResources(), resId);
   this.addCacheBitmap(bmp, resId);
  }
  return bmp;
 }

 private void cleanCache() {
  BtimapRef ref = null;
  while ((ref = (BtimapRef) q.poll()) != null) {
   bitmapRefs.remove(ref._key);
  }
 }

 // 清除Cache内的全部内容
 public void clearCache() {
  cleanCache();
  bitmapRefs.clear();
  System.gc();
  System.runFinalization();
 }

}

在程序代码中调用该类:

imageView.setImageBitmap(bmpCache.getBitmap(R.drawable.kind01, this));

这样当你的imageView需要来回变换背景图片时,就不需要再重复加载。

方法三:

及时销毁不再使用的Bitmap对象。

if (bitmap != null && b!itmap.isRecycled()){

bitmap.recycle();

bitmap = null; // recycle()是个比较漫长的过程,设为null,然后在最后调用System.gc(),效果能好很多

}

System.gc();

方法四:

尽可能少的使用图片资源。

这个有点像废话哈。但我只知道我们经理说服客户改了一下需求,然后在一个动态的listView里(最多时能有100多项),就一下子少加载了几十张网络图片,这该能节约多少内存啊!

综合运用以上四种方法,一般的项目,应该就能避免oom的错误。欢迎一起探讨更好的关于“图片内存溢出问题”的解决方案。


相关文章
|
4月前
|
XML Android开发 数据格式
Android利用selector(选择器)实现图片动态点击效果
本文介绍了Android中ImageView的`src`与`background`属性的区别及应用,重点讲解如何通过设置背景选择器实现图片点击动态效果。`src`用于显示原图大小,不拉伸;`background`可随组件尺寸拉伸。通过创建`selector_setting.xml`,结合`setting_press.xml`和`setting_normal.xml`定义按下和正常状态的背景样式,提升用户体验。示例代码展示了具体实现步骤,包括XML配置和形状定义。
189 3
Android利用selector(选择器)实现图片动态点击效果
|
4月前
|
Java Android开发
Android图片的手动放大缩小
本文介绍了通过缩放因子实现图片放大缩小的功能,效果如动图所示。关键步骤包括:1) 在布局文件中设置 `android:scaleType=&quot;matrix&quot;`;2) 实例化控件并用 `ScaleGestureDetector` 处理缩放手势;3) 使用 `Matrix` 对图片进行缩放处理。为避免内存崩溃,可在全局配置添加 `android:largeHeap=&quot;true&quot;`。代码中定义了 `beforeScale` 和 `nowScale` 变量控制缩放范围,确保流畅体验。
147 8
|
4月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
153 1
|
12月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
161 20
Android经典面试题之图片Bitmap怎么做优化
|
11月前
|
缓存 监控 Java
在使用 Glide 加载 Gif 动画时避免内存泄漏的方法
【10月更文挑战第20天】在使用 Glide 加载 Gif 动画时,避免内存泄漏是非常重要的。通过及时取消加载请求、正确处理生命周期、使用弱引用、清理缓存和避免重复加载等方法,可以有效地避免内存泄漏问题。同时,定期进行监控和检测,确保应用的性能和稳定性。需要在实际开发中不断积累经验,根据具体情况灵活运用这些方法,以保障应用的良好运行。
|
11月前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
Android开发
Android中SurfaceView的双缓冲机制和普通View叠加问题解决办法
本文介绍了 Android 平台上的 SurfaceView,这是一种高效的图形渲染控件,尤其适用于视频播放、游戏和图形动画等场景。文章详细解释了其双缓冲机制,该机制通过前后缓冲区交换来减少图像闪烁,提升视觉体验。然而,SurfaceView 与普通 View 叠加时可能存在 Z-Order 不一致、同步问题及混合渲染难题。文中提供了使用 TextureView、调整 Z-Order 和创建自定义组合控件等多种解决方案。
484 9
|
存储 编解码 缓存
|
存储 编解码 Android开发
Android内存优化-Bitmap内存优化
在日常开发中,我们不免会使用到Bitmap,而bitmap确实实在在的是内存使用的 “大户”,如何更好的使用 bitmap,减少其对 App内存的使用,是我们开发中不可回避的问题。
281 0
Android内存优化-Bitmap内存优化

热门文章

最新文章