目录

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

android mvvm viewmodel获取view id_Android

而jni中最终会调用frameworks/base/core/jni/android_graphics_Canvas.cpp中的CanvasJNI::setBitmap,具体由get_canvas实现setBitmap.

android mvvm viewmodel获取view id_数据结构_02

android mvvm viewmodel获取view id_底层实现_03

而get_canvas得到的是一个hwui/Canvas

android mvvm viewmodel获取view id_Canvas_04

找到Canvas.h后,我们可以看到有setBitmap的方法,但是打开Canvas.cpp之后却发现没有setBitmap的实现

android mvvm viewmodel获取view id_Android_05

android mvvm viewmodel获取view id_基础_06

通过搜索后,我们可以发现,是frameworks/base/libs/hwui/SkiaCanvas.h继承了Canvas

android mvvm viewmodel获取view id_数据结构_07

我们再看SkiaCanvas.cpp中的setBitmap方法可以发现具体操作由mCanvasOwned操控,其持有一个SkCanvas

android mvvm viewmodel获取view id_数据结构_08

android mvvm viewmodel获取view id_底层实现_09

1.3.3 上述的SkCanvas即为Android系统架构中SGL(Skia Graphics Library)中的类,所以说Canvas是Android上层应用的一个数据结构,其具体实现为Skia.

android mvvm viewmodel获取view id_数据结构_10

参考

Canvas API