2012-08-02 9 views
5

ビットマップを含むたくさんのものを描画するカスタムビューがあります。この描画をビットマップにキャッシュしたいので、これらの描画タスクと計算を繰り返すのではなく、onDrawの中に1つのビットマップを描画するだけで済みます。Androidビューでビットマップの割り当てを正しく解除するには?

ビットマップは、使用しなくなった後にリサイクルする必要があります。私は、onDestroy()やViewクラスでは似たようなものは見かけません。これを達成するためにオーバーライドできるコールバックメソッドはありますか?

public void <insert_callback_here>() { 
    cachedBitmap.recycle(); 
} 

アニメーションはありません。これは静的な画像です。画像を描画するのにはたくさんの計算があるので、onMeasure()で一度やります。

答えて

7

私はここに自分自身で答えるつもりです。上書きする適切な方法はonDetachedFromWindowです。私はonDetachedFromWindowの中で私のビットマップの割り当てを解除し、幅や高さが変更された場合はonMeasureの中にそれらを再割り当てします。

@Override 
protected void onDetachedFromWindow() { 
    super.onDetachedFromWindow(); 
    if (cachedBitmap != null && !cachedBitmap.isRecycled()) { 
     cachedBitmap.recycle(); 
     cachedBitmap = null; 
     cachedBitmapWidth = -1; 
     cachedBitmapHeight = -1; 
    } 
} 

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int viewWidth = MeasureSpec.getSize(widthMeasureSpec);; 
    int viewHeight = MeasureSpec.getSize(heightMeasureSpec);; 

    if (cachedBitmapWidth != viewWidth || cachedBitmapHeight != viewHeight) { 
     if (cachedBitmap != null) { 
      cachedBitmap.recycle(); 
     } 
     cachedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
     cachedBitmapWidth = viewWidth; 
     cachedBitmapHeight = viewHeight; 
     Canvas canvas = new Canvas(cachedBitmap); 
     // do drawings here.. 
    } 

    setMeasuredDimension(viewWidth, viewHeight); 
} 
+0

これは私が必要としていたものです。追加するだけで、私は十分なメモリを持つことに問題があったので、ビットマップをリサイクルした後でSystem.gc()も実行しました。 –

+0

良いですが、onCreate()からfinish()を呼び出すアプリケーションには注意が必要です。そのようにメモリリークを起こす可能性があります(https://medium.com/square-corner-blog/android-leak-pattern-subscriptionsを参照)。 -in-views-18f0860aa74c)を参照してください。 – RhetoricalRuvim

+0

重要:onMeasure()とonDraw()の内部に何かを割り当てるのは悪い習慣です。たとえば、レイアウトの階層によっては、ビューの最終サイズが決定される前にonMeasure()が2〜3回呼び出されます。 onSizeChanged()の内部を再配置する方が良いでしょう。 – RhetoricalRuvim

関連する問題