在Android documentation中,它为addView(以及其他一些方法)说明了以下内容:
注意:不要从draw(android.graphics.Canvas)调用此方法, onDraw(android.graphics.Canvas),dispatchDraw(android.graphics.Canvas) 或任何相关的方法。
这种限制的原因是什么?另外,“相关方法”是什么?例如,surfaceChanged这样的方法是什么?
答案 0 :(得分:2)
这是因为在渲染View
时,包含ViewGroup
的{{1}}在映射每个视图将出现在屏幕上的位置时会经历某些步骤。 View
采取的步骤是:
ViewGroup
衡量其所有子视图)ViewGroup
)由于绘制步骤是在屏幕上呈现ViewGroup.LayoutParams
时的最后一步,因此在此过程的这一步添加额外的View
可能会改变(使无效)整个布局。如果您查看View
的源代码,您会看到拨打ViewGroup
会再次启动整个布局过程:
addView(View v)
此外,当public void addView(View child, int index, LayoutParams params) {
if (DBG) {
System.out.println(this + " addView");
}
// addViewInner() will call child.requestLayout() when setting the new LayoutParams
// therefore, we call requestLayout() on ourselves before, so that the child's request
// will be blocked at our level
requestLayout();
invalidate(true);
addViewInner(child, index, params, false);
}
在屏幕上绘制其子ViewGroup
时,它通常会遍历当前添加到View
的所有View
。因此,如果在绘制方法期间调度此类事件,则可能导致ViewGroup尝试绘制尚未完成渲染所需步骤的ViewGroup
。
至于相关方法,这些方法基本上是使View
当前绘图操作失效的方法。
编辑:
SurfaceHolder.Callback方法只是用于跟踪绘图表面状态的ViewGroup
方法,或SurfaceView / GLSurfaceView。由于布局的状态应该保持不变,直到Draw步骤完成,因此在该过程中的那一点上不应该真正需要调用此方法。但是,由于这些方法基本上都是你实现的接口方法(默认情况下它们在源代码中是空的),因此调用其中一种方法应该导致错误的原因应该不是真的,即使我不确定这样做是合适的。如果您的基础实施导致像我上面解释的那样的问题,那么可能会出现问题的一个案例就是......