目录
1.1 是什么?
1.2 与Surface的区别与联系
1.3 底层实现
1.3.2 追踪证明
参考
1.1 是什么?
Android中Canvas类常用于自定义View等操作中,canvas则如同一张画布可以在上面绘制内容,然后这张画布也可以叠加其他的图层或者平移旋转等操作。
Canvas对象的获取方式有两种:一种我们通过重写View.onDraw方法,View中的Canvas对象会被当做参数传递过来,我们操作这个Canvas,效果会直接反应在View中(我们也可以在ViewGroup中对Canvas做操作,然后将这个Canvas通过diapatchDraw(Canvas)的方式传递给子View,子View将会按照Canvas的规则去绘制)。另一种就是new的方式去创建咯。
Canvas类持有“draw”调用。要绘制内容,您需要4个基本组件:一个用于持有像素的Bitmap,一个用于承载绘制调用的Canvas(写入位图),一个绘制图元(例如Rect,Path,文本,Bitmap)和一个画笔Paint( 描述图纸的颜色和样式)。
1.2 与Surface的区别与联系
Canvas是Java层构建的数据结构,是给View用的画布,ViewGroup会将Canvas拆分给子View,在onDraw方法里将图形数据绘制在它获得的Canvas上。
Surface是Native层构建的数据结构,是给SurfaceFlinger用的画布,它是直接被用来绘制到屏幕上的数据结构。
DecorView的Canvas信息会转换到一个Surface上。SurfaceFlinger会将各个应用窗口的Surface进行合成,最终绘制到屏幕上
1.3 底层实现
1.3.1 Canvas底层具体实现其绘制的,是Skia.
1.3.2 追踪证明
我们以Canvas.setBitmap为例,进行追踪,可以看到其最终是调用了jni方法nSetBitmap
而jni中最终会调用frameworks/base/core/jni/android_graphics_Canvas.cpp中的CanvasJNI::setBitmap,具体由get_canvas实现setBitmap.
而get_canvas得到的是一个hwui/Canvas
找到Canvas.h后,我们可以看到有setBitmap的方法,但是打开Canvas.cpp之后却发现没有setBitmap的实现
通过搜索后,我们可以发现,是frameworks/base/libs/hwui/SkiaCanvas.h继承了Canvas
我们再看SkiaCanvas.cpp中的setBitmap方法可以发现具体操作由mCanvasOwned操控,其持有一个SkCanvas
1.3.3 上述的SkCanvas即为Android系统架构中SGL(Skia Graphics Library)中的类,所以说Canvas是Android上层应用的一个数据结构,其具体实现为Skia.