Android 如何有效地回收按以下代码创建的位图?

Android 如何有效地回收按以下代码创建的位图?,android,bitmap,recycle,Android,Bitmap,Recycle,我已经创建了如下位图 //在下面的行中创建位图 位图myBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.googlelogo320x480) 我已将其设置为ImageView 我的问题是: 1> 我是否需要在上面的位图上显式调用Bitmap.recycle()? 2> 如果是的话,我应该什么时候打电话?我尝试在第三行之后立即调用它,即在将位图设置为ImageView之后,但是我得到一个例外,Canvas尝试绘制回收对象。

我已经创建了如下位图

//在下面的行中创建位图
位图myBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.googlelogo320x480)
我已将其设置为ImageView

我的问题是: 1> 我是否需要在上面的位图上显式调用Bitmap.recycle()? 2> 如果是的话,我应该什么时候打电话?我尝试在第三行之后立即调用它,即在将位图设置为ImageView之后,但是我得到一个例外,Canvas尝试绘制回收对象。 3> 如果在我的代码中从未对位图调用recycle(),是否会导致内存泄漏? 附言:我正在从事ICS或以上的工作。

试试这个

if (myBitmap != null) {
    myBitmap.recycle();
    myBitmap = null;
}
Bitmap original = BitmapFactory.decodeFile(myFile);
myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true);
original.recycle();
original = null;
试试这个

if (myBitmap != null) {
    myBitmap.recycle();
    myBitmap = null;
}
Bitmap original = BitmapFactory.decodeFile(myFile);
myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true);
original.recycle();
original = null;
不调用recycle()不会导致内存泄漏,但可能会导致应用程序超出内存限制并爆炸,请参阅下面的内容以查看应用程序是否符合要求:

  • 如果您只对ICS及以上版本感兴趣,则不必担心调用recycle(),因为位图的实际备份数据存储在Dalvik控制的内存中。因此,只要不保留对位图的引用,Dalvk应该能够毫无问题地对其进行GC
  • 即使您希望支持Android 2.3或更高版本,位图最终也会发布,所以如果您的应用程序不是位图密集型的,您也不必担心
  • 但是,如果您支持Android 2.3或更高版本,并且使用了大量位图,那么您应该在完成位图后立即回收位图
  • 不调用recycle()不会导致内存泄漏,但可能会导致应用程序超出内存限制并爆炸,请参阅下面的内容以查看应用程序是否符合要求:

  • 如果您只对ICS及以上版本感兴趣,则不必担心调用recycle(),因为位图的实际备份数据存储在Dalvik控制的内存中。因此,只要不保留对位图的引用,Dalvk应该能够毫无问题地对其进行GC
  • 即使您希望支持Android 2.3或更高版本,位图最终也会发布,所以如果您的应用程序不是位图密集型的,您也不必担心
  • 但是,如果您支持Android 2.3或更高版本,并且使用了大量位图,那么您应该在完成位图后立即回收位图

  • 在这种情况下,不应该调用recycle();处理完后,
    ImageView
    将调用recycle()。这已经是事实了一段时间,ICS并没有改变这一事实

    代码处理完图像后,需要调用recycle()。例如,如果要对一个图像应用10个过滤器并在每个步骤上生成新位图,则应在每个步骤后对旧位图调用recycle()


    也就是说,您不能同时拥有无限数量的位图,尤其是大型位图。这时您需要更聪明,动态加载/卸载。

    在这种特殊情况下,不应该调用recycle();处理完后,
    ImageView
    将调用recycle()。这已经是事实了一段时间,ICS并没有改变这一事实

    代码处理完图像后,需要调用recycle()。例如,如果要对一个图像应用10个过滤器并在每个步骤上生成新位图,则应在每个步骤后对旧位图调用recycle()


    也就是说,您不能同时拥有无限数量的位图,尤其是大型位图。这时你需要变得聪明,动态加载/卸载。

    我的问题是ICS或更高版本的Android真的需要它吗。如果需要的话,什么时候调用?一个活动的onDestroy()将太晚,因为到那时我将运行OOM Exception。我的问题是,ICS或更高版本的Android是否真的需要它。如果需要的话,什么时候调用?活动的onDestroy()将太迟,因为届时我将运行OOM异常,因为我在应用程序中使用了大量位图,所以即使使用ICS或更高版本,我也可能需要调用recycle?同样在你的第一点中,“因此,只要你不保留对位图的引用,Dalvk应该能够毫无问题地GC它。”不保留引用意味着什么?我正在将每个位图设置为Imageview,基于方向更改或每当需要更新图像时,我将在for循环中再次创建新的Imageview和新的位图实例。如果您的代码中没有任何地方引用Imageview,则Android将在不确定的时间发布它。如果要在for循环中分配大量位图,则可以尝试将System.gc()放在for循环之前,并在实际设备上进行测试,以查看是否确实遇到OoM。我已经在本活动中遇到了OoM,其他一些文件将由我的活动的调用触发。在那个文件中,他们正在尝试创建一个新的位图,这就是它抛出OOM的地方。我自己的代码中还有一个OOM,在创建许多位图的for循环之前,我实际上在尝试添加解码2个位图,大约9KB,如下代码,Bitmap bmp=BitmapFactory.DecodeResource(参考资料,R.drawable.myImage);在这里它也崩溃了,因为OOM,我已经通过使用采样率在一定程度上解决了这个问题。然而,我只是想知道为什么第一次发生OOM。此外,此采样修复程序将降低可能性,但它不能保证在解码位图资源时消除OOM问题。一个可能的原因是您创建的位图太多或其大小太大。另一个原因可能是您创建它们的方式:通过for循环。这样做可能不会给Android足够的时间进行GC。您可以通过调用Thread.yield()来消除这种可能性;或线程。睡眠(50);在for循环中创建每个位图之后。如果你仍然得到OoM,那么可能是因为原因#1。是的,我在我的应用程序中使用了很多位图,所以即使使用ICS或更高版本,我也可能需要调用recycle?也在你的第一点“Therefo”