【问题标题】:StackOverflowError when calling getDrawingCache() from onDraw()从 onDraw() 调用 getDrawingCache() 时出现 StackOverflowError
【发布时间】:2012-12-10 17:06:24
【问题描述】:

我有一个手动绘制的自定义视图。我正在将东西绘制到位图中,然后在 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),否则这不会发生。并且仅当视图附加到父视图时才设置该标志,是硬件加速并且层类型为 LAYER_TYPE_NONE (source again)。

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

【问题讨论】:

  • 如果你的方法依赖于其他类的未记录的内部状态,那就不行了。它很可能会在较新的版本中出现问题,并且可能会在您尚未测试的许多其他版本中出现问题。 (并且可以禁用硬件加速)

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


【解决方案1】:

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

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

【讨论】:

  • 我的视图基本上是一个带有自定义绘图的大画布。我正在像这样进入绘图缓存:cache_canvas.setBitmap(getDrawingCache()); perform_drawing_into_cache_canvas。如果我使用自己的位图,我应该禁用缓存是对的吗?
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 2017-05-07
  • 2016-07-29
相关资源
最近更新 更多