2010-11-25 10 views
0

私のアプリケーションには3つの画像リソースがあります。 ImageViewにそれらのいずれかをロードして表示することはスムーズに行われます。 しかし、レイアウトから表示されたImageViewを削除すると、nullとなり、 新しい画像を追加すると、奇妙なことが起こります。古いビットマップ上画像処理でのプロセスクラッシュ(シグナル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が得られます。コールスタックは次のとおりです。

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 
... 

明らかにAndroidにはバグがありますが、避けられないようです。

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がロードされアンロードされているからです。 しかし、あなたが提案した解決策は、私が掲示した問題を解決し、リサイクルコールを一掃し、System.gc()コールをいくつかの場所に広めることについて考えさせました。 ご協力いただきありがとうございます! – Roi

0

私は何とか画像キャッシュをクリアしようとしています...私は私と同様の問題を抱えていました。私の投稿ですSIGNAL 11 SIGSEGV crash Android