使用传感器侦听器使用大量图像时出现异常错误

时间:2011-06-13 11:25:12

标签: android bitmap out-of-memory sensor

我正在开发一个具有大量图像的应用程序,并使用传感器监听器,我在活动开始时使用传感器管理器注册,以检测抖动事件并根据抖动方向更改图像。

我在onSensorChanged(SensorEvent event)中读取了事件值,以便在我的应用中使用它:

public void onSensorChanged(SensorEvent event){
     accX = event.values[0];
     accY = event.values[1];
     accY = event.values[2];
 }

我在活动暂停时取消注册传感器监听器,并调用system.gc进行垃圾收集。

在我参与单一活动之前一切正常。

当我完成当前活动并打开另一个活动(再次拥有一个传感器监听器)时,应用程序会在一段时间后开始给出内存异常:

  

“OutOfMemoryException:位图大小   超过VM预算“

请注意,应用的堆大小不会超过4 MB。

还有一个观察结果是,如果没有使用传感器监听器,应用程序永远不会崩溃,这使得我认为生成传感器事件时可能存在内存泄漏,并且当加载新活动时,由于可用内存较少,应用程序给出在活动中使用位图时OutOfMemoryException。

所以看似有两个可能的原因:

  1. 图片无法正常回收 http://code.google.com/p/android/issues/detail?id=8488
  2. 每次有一个SensorEvent,某处存在内存泄漏,这会减少应用程序的可用内存 Android: reading accelerometer without memory allocation?
  3. 我也在使用评论51中描述的解决方案: http://code.google.com/p/android/issues/detail?id=8488

    回收所有东西,但它仍然会造成内存问题。

    如果你能告诉我在大尺寸应用程序中使用图像的最佳方法,如何回收它们并确认在使用传感器监听器时是否确实存在任何内存泄漏,或者我应该在应用程序,它将非常有用。

2 个答案:

答案 0 :(得分:0)

要使图像正确回收,如果可能,请尝试使用Bitmap.recycle()方法。这是因为图像实际上是作为参考保存的(在预蜂窝中),实际数据是使用本机内存分配的。

在Honeycomb中,图像的内存在堆上分配,因此它很容易被GCed。此外,您可以设置largeHeap =“true”(再次命名为Honeycomb)。

答案 1 :(得分:0)

仅供参考,您可以使用SoftReferenceHashMap的组合来实现对位图的更好内存控制。通过使用SoftReference,当内存不足时,将不再引用对象来释放内存。

一个常见例子:

HashMap<String, SoftReference<Bitmap>> cache;
...
Bitmap bitmapToRead = cache.get(key).get();
if (bitmapToRead == null){
  cache.put(key, new SoftReference<Bitmap>(bitmap)); // bitmap from Storage for example
  /* your operation */
}else{
  /* your operation on bitmapToRead */
}

但说实话,我经历过OutOfMemoryError甚至使用SoftReference<Bitmap>。我为克服此错误所做的是手动recycle()位图。