2010-11-25 30 views
0

我在我的应用程序中有3个图像资源。 在ImageView中加载和显示它们中的任何一个都可以顺利进行。 但是,当我从布局中删除显示的ImageView时,将其添加一个新图像,然后 会变得奇怪。图像处理过程崩溃(信号11)

要么进程崩溃完全(信号11)当我尝试对旧的位图 调用.recycle()或我得到 情况下,我不使用回收OutOfMemoryError异常。

这只发生在8以下的API级别,所以我的猜测是本地堆上的 GC错误导致它并且这些错误被固定在 2.2。然而,因为2.1是目前最常见的版本,所以我需要一个解决方法...

同样,本地堆应该不会缺少内存。我一次只持有 只有1张图像,并且无效,所以GC应该能够 检索堆空间(就像2.2上发生的那样)。

我创建了一个非常小的样本应用程序,它可以从 这里下载: http://www.4shared.com/file/QqHrhJLR/BitmapRecycleTest.html

任何建议将不胜感激。

回答

1

我看了一下。我在运行2.2.1的Nexus One上获取信号11。这个callstack是这样的:

I/DEBUG ( 56):   #00 pc 0000c584 /system/lib/libc.so 
I/DEBUG ( 56):   #01 pc 0000cd2e /system/lib/libc.so 
I/DEBUG ( 56):   #02 pc 0002c5dc /system/lib/libskia.so 
I/DEBUG ( 56):   #03 pc 00068108 /system/lib/libskia.so 
I/DEBUG ( 56):   #04 pc 00063a8c /system/lib/libskia.so 
I/DEBUG ( 56):   #05 pc 0004cefc /system/lib/libandroid_runtime.so 
I/DEBUG ( 56):   #06 pc 00016e34 /system/lib/libdvm.so 
I/DEBUG ( 56):   #07 pc 000452c4 /system/lib/libdvm.so 
I/DEBUG ( 56):   #08 pc 0001bd98 /system/lib/libdvm.so 
... 

很明显这里有一个bug,但它似乎是可以避免的。

不要使用你的BitmapResource类......你应该明确地回收()你的位图时,你不再需要它们。我改变了你的DrawView构造函数:

public DrawView(Context context, int resId) { 
    super(context); 
    setImageResource(resId); 
} 

由于你的图像太大 - 7MB解压缩! - 在删除上一张图像后,我还添加了一个System.gc()buttonClickHandler现在看起来是这样的:

public void buttonClickHandler(View v) { 
    Object tagObj = mSwitchButton.getTag(); 
    if (tagObj != null && tagObj instanceof ImageView) { 
     ImageView iv = (ImageView)tagObj; 
     iv.setImageBitmap(null); 
      mMainLayout.removeView(iv); 
     System.gc(); 
    } 

    addNewViewToLayout(mMainLayout); 
} 

有了这些改变你的应用程序运行对我罚款。

+0

我发布的示例应用程序是“重现的最小代码”,它来源于我遇到此问题的大得多的应用程序。 我需要BitmapResource,因为在大型应用程序中,此类中有更多的逻辑。在它的终结器中的.recycle调用是因为我有很多bmp被加载和卸载,所以我不能显式地调用recycle(),因为我会在所有地方回收调用。 但是,您建议的解决方案确实解决了我发布的问题,并让我考虑完全放弃回收呼叫,并在某些地方传播System.gc()调用。 感谢您的帮助! – Roi 2010-11-25 16:53:36

相关问题