2012-08-02 57 views
5

我有一个自定义视图,绘制了一堆东西,包括位图。我想将此图形缓存到位图上,这样我只需要在onDraw中绘制一个位图,而不是重复这些绘图任务和计算。在Android视图中正确释放位图的位置?

在我们不再使用它之后,位图需要回收。我没有在View类中看到onDestroy()或任何类似的东西。有没有可以覆盖的回调方法来实现这一点?

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(),因为我有足够的内存有问题。 – 2013-01-09 08:18:45

+0

不错,但是要注意onCreate()调用finish()的应用程序:它可以通过这种方式使内存泄漏(请参阅https://medium.com/square-corner-blog/android-leak-pattern-subscriptions -in-视图-18f0860aa74c)。 – RhetoricalRuvim 2017-12-22 19:12:20

+0

同样重要的是:在onMeasure()和onDraw()内分配任何东西是不好的做法。举例来说,这取决于布局的层次结构,onMeasure()被确定视图的最终尺寸之前被称为像2或3次。在onSizeChanged()中重新分配会更好。 – RhetoricalRuvim 2017-12-24 01:39:28