3

我已经阅读了大量关于这两个错误的帖子,但似乎找不到适合我的解决方案。我有一个基本的动物列表视图活动。当您单击列表中的某个项目时,它会打开 AnimalViewActivity 并在 ImageView 中显示一个简单的 png 图像。

这是我为 ImageView 设置图像的地方:

public void getImage() {

    String imageName = myService.yourAnimals.get(key).getType();
    System.out.println(imageName);

    Resources res = getResources();
    int resourceId = res.getIdentifier(imageName, "drawable", getPackageName() );
    Drawable drawable = res.getDrawable( resourceId );
    image.setImageDrawable( drawable );
}

然后当我离开 AnimalViewActivity 返回 listview 活动时,我这样做:

@Override
protected void onDestroy() {
    super.onDestroy();
    //((BitmapDrawable)image.getDrawable()).getBitmap().recycle();
    image.getDrawable().setCallback(null);
    //System.gc();
    System.out.println("Destroy image!");
}

如果我取消注释 recycle() 行,我会收到“无法绘制回收位图”错误。如果我让它保持原样,我会得到 bitmapfactory 的 outofmemoryerror。

java.lang.IllegalArgumentException:无法绘制回收位图或 java.lang.OutOfMemoryError android.graphics.BitmapFactory.nativeDecodeAsset(本机方法)

在我打开 ViewAnimalActivity 大约 20 次并且应用程序崩溃后,这些错误中的任何一个都会发生。唯一似乎永远有效的是 System.gc() ,但我知道这不是一个好的解决方案。

我在android4.1中测试,但是minSDK设置为android3.0

我读到位图回收的 javaVM 错误在 3.0 中已修复?

出于某种原因,如果不显式调用 gc,垃圾收集的速度不够快。这些图像很小,大多在 100-300kB 之间。

有任何想法吗?


编辑: image.setImageDrawable(null);似乎更快乐

我想我之前在 Android2.2 上设置它时也尝试过,但到目前为止,Android3.0 对它很满意。

4

2 回答 2

3

recycle() 的文档明确指出它用于“高级用途”。实际上,将引用设置为 null 更为重要。

这是一个高级调用,通常不需要调用,因为当没有更多对该位图的引用时,正常的 GC 进程将释放此内存。

此外,还可以在绘制位图之前查看它是否已被回收。(发布您的 logcat 以查看您遇到错误的位置。您可以添加代码以验证 Bitmap 是否已被回收并重新加载)。

总的来说,我认为你最好看看告诉你如何有效显示位图的 Android 培训课程。

于 2013-03-08T00:10:37.263 回答
0

你为什么不先尝试将drawable设置为null,然后回收它?问题可能是因为当你回收它时drawable仍然在图像上,从而导致“无法绘制回收的位图错误”。如果您首先将其设置为 null,从而将实际的 ImageView(或您正在使用的任何内容)设置为 null,然后将其回收,这可能会解决您的问题。

编辑:哇!我完全忘记了如果您将可绘制对象设置为空,那么您将无法检索您要回收的位图。尝试先将其分配给一个变量,然后再循环它。

于 2013-03-08T00:45:36.147 回答