初探 :
普通View只能在主线程绘制图形,并在回调主线程中改变view 重新绘制view。
holder中保存着surfaceView中对应的区段
给canvas加上锁
holder.lockCanvas() unlockCanvas()
unlockAndPostCanvas(canvas)
为了监听这个内存区的生存期,于是有回调方法 callBack 控制 onViewCreate onViewDestory等等
其实所有绘制图像,都是由Surface完成。
屏幕绘图的软件架构F
在Android 系统底层有SufaceFlinger服务进程,整个系统只有一个,在开机时自动运行,作用是给每个客户端分配窗口。
程序中用Surface类表示这个窗口,每个平面在程序中都对应一段内存,。
我们通过SurfaceFlinger客户端来和SurfaceFlinger进行沟通,使用该进程的是SystemServer进程。
当程序需要创建窗口时,首先在本地创建Surface对象,然后通过WindowManager对WMS服务发起请求,将surface引用 交给它初始化,就是给该Surface对象分配一段屏幕缓冲区内存。 WMS通过SF客户端请求SF创建一段屏幕缓冲区,并在sf内部记录下来,然后把缓冲区地址交个WMS,完成Surface的初始化。
程序拥有这个Surface后,就可以给这个平面上绘制任意内容,但是怎样在这段缓冲区内存中绘制图形。这就要使用到绘图驱动库,作用是进行各种平面绘制,这就是Canvas这个对象的作用,Surface类通过lockCanvas()返回一个Canvas对象,利用该对象的 drawColor(),drawLine() 等一系列API完成 对平面绘制功能。
自定义SurfaceView中的图形绘制是由holder管理获取Canvas
但是在系统控件是怎样绘制出来的,Surface又扮演怎样的角色? 控件中onDraw(Canvas canvas) 中的canvas又是怎么来的?
整个绘制过程是从 ViewRoot的performTraversals()函数开始,首先开始调用 ViewRoot中draw(),该函数检查Surface是否有效的,并且判断是否有程序定义的,还是系统分配的,如果为程序定义的就交个程序独立处理。
如果是由系统分配的,并且使用openGL对应的Surface,就按照GL方式去处理,拿到全局变量mGlCanvas作为canvas值,并保存Canvas对象属性,并且将它交个视图树层层绘制,mView.draw(canvas) 。这就是普通控件Canvas的来源。