20

私が理解しているように(私が正しいというわけではありません)、ドローアブルは通常、アプリケーションが終了するとメモリから正しく削除されます。ただし、ビットマップは手動で再利用する必要があり、適切に処理するために特別なクラスが記述されている場合もあります。私の質問は、メモリとリークに関して、次のようなDrawables に固執する方が有益かということです。

myView.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image));
myView1.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image1));
myView2.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image2));

ビットマップのようなものではなく:

Bitmap tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
myView.setImageBitmap(tmpBitmap);

tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image1);
myView1.setImageBitmap(tmpBitmap);

tmpBitmap.recycle();
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image2);
myView2.setImageBitmap(tmpBitmap);
tmpBitmap.recycle();

もちろん、使用中に削除できるため、ビットマップの recycle() メソッドに注意する必要があることも読みましたか? これらの問題はさまざまな形で発生し続けているようですが、この問題について誰からも率直な回答を得ることができません. ある人はビットマップを再利用し、毎回使用後にリサイクルすると言い、他の人は Drawables と unbindDrawables() メソッドを使用すると言います (これは私が使用しているものです)。

private void unbindDrawables(View view) {
    if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}

ただし、該当する洞察は大歓迎です。ありがとう

4

2 に答える 2

9

ビットマップを手動でリサイクルする必要はありません。これらは、Drawable やその他のオブジェクトと同様にガベージ コレクションされます。同様に、非常に特殊な状況を除いて、ドローアブルのバインドを解除する必要はありません。誤解を招く情報をたくさん読んだようです。

ビットマップのリサイクルとドローアブルのバインド解除は、状況によっては便利です (たとえば、アプリが大量のビットマップ データを操作する場合や、ドローアブルを静的な方法で保存する場合など)。

質問の冒頭で示した 2 つの例は同等です。ドローアブルを直接ロードすると、代わりにビットマップがロードされます。ビットマップを手動でロードして ImageView に設定すると、代わりにドローアブルに含まれます。

最初の解決策はより単純であり、実際に必要になるまでバインド解除やその他のメモリ管理手法について心配する必要がないため、最初の解決策を使用してください。

于 2011-08-12T18:59:23.310 に答える
8

私は Romain の提案を支持しますが、あなたの質問が実際の問題に対処しているかどうかはわかりません。ビューへの参照をどのように処理するかわかりません。アプリケーションで単にメモリ リークが発生している可能性がありますか? Android でのメモリ リークの多くは、Context. Drawableが にアタッチされている場合、ViewViewのコールバックとして設定されますDrawable

TextView myView = new TextView(this);
myView.setBackgroundDrawable(getDrawable(R.drawable.my_bitmap));

上記のコード スニペットでは、これは、Drawableが への参照をTextView持ち、それ自体がActivity( Context) への参照を持ち、コードに応じてほとんどすべてへの参照を持つことを意味します。

あなたのコードをもっと見なくても、格納されたドローアブルのコールバックをnullanActivityが破棄されたときに設定することで、正しい軌道に乗っていると思います。

于 2011-08-12T22:33:53.073 に答える