文章目录
- 一、Canvas 状态栈入栈与出栈
- 二、获取 Canvas 状态栈容量
- 三、Canvas 状态栈原点数据
Canvas 状态保存机制 中 , 存在两个栈结构 , 分别是 状态栈 和 图层栈 ;
其中 图层栈 又称为 Layer 栈 ;
一、Canvas 状态栈入栈与出栈
状态栈 用于保存 绘图坐标系 信息 ,
- 每次调用 Canvas#save() 方法 , 都会向 状态栈 中存储一份坐标数据 , 即 入栈操作 , 状态栈 是 后入先出 的栈结构 数据 ;
- 每次调用 Canvas#restore() 方法 , 就是将 状态栈 栈顶的坐标数据 , 进行 出栈操作 ;
Canvas#save() 方法函数原型 :
代码语言:javascript复制 /**
* 保存当前矩阵并将其剪辑到私有堆栈上。
*
* 随后对translate、scale、rotate、skew、concat或clipRect、clipPath的调用都将照常运行,
* 但当对restore()进行平衡调用时,这些调用将被忘记,并且将恢复save()之前存在的设置。
*
* @return 传递给restoreToCount()以平衡此save()的值
*/
public int save() {
return nSave(mNativeCanvasWrapper, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
}
Canvas#restore() 方法函数原型 :
代码语言:javascript复制 /**
* 此调用平衡了之前对save()的调用,并用于删除自上次save调用以来对矩阵/片段状态的所有修改。
* 调用restore()的次数比调用save()的次数多是错误的。
*/
public void restore() {
if (!nRestore(mNativeCanvasWrapper)
&& (!sCompatibilityRestore || !isHardwareAccelerated())) {
throw new IllegalStateException("Underflow in restore - more restores than saves");
}
}
二、获取 Canvas 状态栈容量
通过调用 Canvas#getSaveCount() 方法 , 可以 获取当前 Canvas 画布的 状态栈 容量 , 当前缓存了多少个 坐标数据 , 也就是调用了多少次 Canvas#save() 方法 ;
Canvas#getSaveCount() 函数原型 :
代码语言:javascript复制 /**
* 返回画布私有堆栈上的矩阵/剪辑状态数。
* 这将等于#save()调用-#restore()调用。
*/
public int getSaveCount() {
return nGetSaveCount(mNativeCanvasWrapper);
}
三、Canvas 状态栈原点数据
Canvas 的 状态栈 中, 默认存在一个数据 , 就是 原点 坐标数据 , 也就是即使不调用 Canvas#save() 方法 , 直接调用 Canvas#getSaveCount() 方法获取的值是 1 ;
如果没有调用 Canvas#save() 方法 , 直接调用 Canvas#restore() 方法 , 就会将 状态栈 中的 原点坐标数据 出栈 , 该操作会导致程序崩溃 , 崩溃信息如下 :
代码语言:javascript复制2022-07-05 18:08:53.073 22010-22010/kim.hsl.android_ui E/AndroidRuntime: FATAL EXCEPTION: main
Process: kim.hsl.android_ui, PID: 22010
java.lang.IllegalStateException: Underflow in restore - more restores than saves
at android.graphics.Canvas.restore(Canvas.java:605)
at kim.hsl.android_ui.PathMeasureView3.onDraw(PathMeasureView3.java:38)
at android.view.View.draw(View.java:20207)