通过 ACRA,我收到了少量来自 alpha 版本软件的报告,这些报告表明在特定调用Canvas.restore()
. 例外是java.lang.IllegalStateException: Underflow in restore
。
我很清楚,如果restore()
拨打电话的次数多于save()
通话次数,则会发生此异常。但是,通过非常仔细的代码检查,我绝对可以肯定所有对canvas.save()
和的调用canvas.restore()
都是平衡的。也就是说,所有对canvas.save()
的调用肯定会在稍后阶段通过对 的调用来平衡canvas.restore()
。我还可以确认没有可能导致丢失canvas.save()
导致堆栈下溢的方法的条件、异常或提前返回。
此外,这个问题似乎是一种罕见的边缘情况,它导致在每秒渲染多次的图形代码中仅发生几次异常。
发生这种情况的代码结构是:
protected void onDraw(Canvas canvas) {
...
someMethod(canvas);
...
}
void someMethod(Canvas canvas)
{
....
canvas.save();
....
someOtherMethod(Canvas canvas);
....
canvas.restore();
....
}
void someOtherMethod(Canvas canvas)
{
....
canvas.save();
....
for ( ... ) {
....
canvas.save();
...
canvas.restore();
...
}
....
canvas.restore(); // *** exception here ***
....
}
有些地方save()
/restore()
在循环中使用,但调用也是平衡的。
报告来自运行 4.3 和 4.4.2 的设备。
我试图用谷歌搜索这个问题,我能找到的唯一有趣的 QA 来自一个在他的代码中显然有不平衡的 save() / restore() 调用的人;这绝对不是我的问题。
这发生在自定义 View 子类的onDraw(Canvas canvas)
方法的调用堆栈中,所有这些都发生在 UI 线程上。我没有接触过该Canvas
对象的其他线程。
getSaveCount()
在调用负责异常的特定 restore() 之前,我可能会通过调用来检查堆栈,但这实际上只是在问题上坚持使用 Elastoplast。我宁愿了解导致下溢的边缘情况到底是什么,但这让我感到困惑。
是否有任何已知问题?Canvas
当 UI 线程在 aView
的onDraw()
调用上下文中时,任何类型的系统配置更改都可能影响这一点吗?Canvas
堆栈大小是否有任何已知限制?是否存在已知滥用画布堆栈的任何操作系统图形调用?