从onDraw()调用getDrawingCache()时的StackOverflowError

时间:2012-12-10 17:06:25

标签: android stack-overflow android-3.0-honeycomb

我有一个手动绘制的自定义视图。我正在将内容绘制到位图中,然后在onDraw()中使用该位图。我意识到,如果我启用绘图缓存,我可以使用该缓存而不是创建自己的位图。这大部分都有效。

目前我的onDraw方法如下所示:

protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(getDrawingCache(), 0, 0, null);
}

这适用于我尝试过的模拟器。但是我在StackOverflowError上收到崩溃报告。报告看起来像这样:

java.lang.StackOverflowError
at android.view.View.getDrawingCache(View.java:10481)
at android.view.View.getDrawingCache(View.java:10446)
at com.aragaer.jtt.JTTClockView.onDraw(JTTClockView.java:162)
at android.view.View.draw(View.java:10983)
at android.view.View.buildDrawingCache(View.java:10700)
at android.view.View.getDrawingCache(View.java:10481)
at android.view.View.getDrawingCache(View.java:10446)
and so on...

我看过android源码,实际上是buildDrawingCache调用draw()。这可以解释循环。但是buildDrawingCache()应该在第二次调用时立即返回。

除非设置了PFLAG_DRAWING_CACHE_VALID(source),否则不会发生这种情况。并且仅当视图附加到父级时才设置该标志,IS硬件加速AND层类型为LAYER_TYPE_NONE(source again)。

问题是 - 是否可以将图层类型显式设置为非-n或者我应该使用其他方法?如果是,我应该选择哪种类型?

1 个答案:

答案 0 :(得分:5)

getDrawingCache()从未打算被View本身使用。它由父母管理。当View是硬件加速时未设置标志的原因是因为“绘图缓存”与硬件加速具有不同的含义。它用于控制显示列表的生命周期。即使你想要它时设置了标志,你也不会得到你想要的行为。

此处有两种解决方案:创建自己的位图或更好,只需在视图上启用绘图缓存,不要从canvas.drawBitmap(getDrawingCache(), ...)调用onDraw()。无论如何,父母会为你做这件事!