web-dev-qa-db-ja.com

ImageViewのビットマップをリサイクル

私はこのようなものを持っています:

Bitmap.Config conf = Bitmap.Config.ARGB_8888;
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, conf));

Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);

imageView.setImageBitmap(bm);

そして、これを1つずつ作成される10を超えるimageViewに適用します。新しいImageViewを作成するたびに、最初のオブジェクトから「bm」オブジェクトをリサイクルし、そこにこのコードを作成し、ヒープをますます大きくしてからOutOfMemoryErrorをスローしたいので、

bm.recycle()

ビットマップ(bm)をimageViewオブジェクトに設定した直後。これにより、ImageViewのキャンバスがリサイクルビットマップを描画するという例外が発生します。

ImageViewに既にイメージとして配置されているビットマップをリサイクルする方法は何ですか?

Thanksb

38
Peter Olsbourg

OnDestroyメソッドでは、次のようなものを試すことができます。

ImageView imageView = (ImageView)findViewById(R.id.my_image);
Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    Bitmap bitmap = bitmapDrawable.getBitmap();
    bitmap.recycle();
}

SetImageBitmapは次のように実装されているため、キャストは機能するはずです。

public void setImageBitmap(Bitmap bm) {
    setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
56
devconsole

すべてのImageViewsに同じビットマップオブジェクトを設定した場合、OutOfMemoryErrorはスローされません。基本的に、これは動作するはずです:

WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, Bitmap.Config.ARGB_8888));

Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);

imageView1.setImageBitmap(bm.get());
imageView2.setImageBitmap(bm.get());
imageView3.setImageBitmap(bm.get());
imageView4.setImageBitmap(bm.get());
imageView5.setImageBitmap(bm.get());
// ...

これが機能しない場合、ビットマップが大きすぎることを意味します(正しく計算した場合、6000x2000ピクセルは約12メガバイトです)。次のいずれかを実行できます。

  • ビットマップを小さくする
  • 多くのメモリを使用する他のものを削減
2
Felix

Devconsoleの答えは素晴らしいですが、クラスのメンバーのようなリストにすべてのビットマップオブジェクトを保存し、アクティビティのonDestroy()メソッド(またはビットマップを使用するコンポーネントの他のリリースライフサイクルメソッド)がサイクルするときにそれらをリサイクルすることもできます呼ばれる。

1