Android绘图基础--Surface创建及初始化

来源:互联网 发布:java发送邮件 多邮箱 编辑:程序博客网 时间:2024/06/05 06:12

Android绘图基础–Surface创建及初始化

一个Window将和一个Surface绑定,绘制前ViewRootImpl会从Surface中lock除一个Canvas。同一个ViewRootImpl不同类型的View使用同一个Surface。SurfaceView除外,它是绘制在单独线程,并且由应用层主动调用locakCanvas、draw等完成绘制,相当于抛开ViewRootImpl控制直接和屏幕通信。

WMS创建Surface过程如下图:

一、ViewRootImpl中的初始化。

  • Activity调用setContentView()后经过一系列调用会新建一个ViewRootImpl对象,该对象是所有视图的根,但是不参与具体内容绘制,负责该Activity具体视图的行为控制、绘制、事件输入等。这里当新建一个ViewRootImpl对象同时其内部会新建一个Surface对象,这里的Surface对象内部还没有任何内容。

  • 创建完成ViewRootImpl对象调用到其内部方法setView(),在该方法中需要关注两处调用:第一是requestLayout()会发布异步任务执行关于整个View的重新计算布局绘制的过程。第二是Session.addToDisplay()通知远程WMS进行窗口添加显示逻辑。

二、先看Session.addToDisplay()调用。

  • Session.addToDisplay()内部通过IPC调用到WMS同名方法,首先会新建一个WindowState保存下传入变量,通过调用WindowState.attach()在该函数中又会调用到Session.windowAddedLocked()内部创建一个SurfaceSession对象,在这个对象的构造函数中调用nativeCreate(),该函数会在native层与处于后台进程的SurfaceFlinger通信。

三、requestLayout()是异步任务。

  • 通过一系列调用来到WMS.relayoutWindow(),该方法内部调用WindowAnimator.createSurfaceLocked()函数,其内部新建一个SurfaceControl对象,该对象构造过程中会拿着上买呢的SurfaceSession对象与SF通信。

  • 创建完成后调用outSurface.copyFrom()将创建成功的SurfaceControl传入在native创建真正又内容的Surface并且赋值给outSurface。这里可以将outSurface对象看成是通过ViewRootImpl传进来的空Surface对象。

以上简单总结:

1.首先在WMS中创建一个SurfaceSession与SF服务通信建立。

2.使用SurfaceSession创建一个真正实现的Surface对象并且发送给客户端进程的ViewRootImpl对象。

上述步骤三ViewRootImpl.relayout()的调用传入ViewRootImpl中的Surface空对象,其真正赋值过程如下:

  • ViewRootImpl.relayout()传入空Surface内部调用到Session.relyout();接着进行IPC调用。

  • 通过查看AIDL文件生成的代码可知在IWindowSession.Stub.Proxy.relayout()进行IPC调用时传入的Surface对象并没有真正写入Parcel即没有传递给WMS。

那么WMS是如何做上述步骤三中的outSurface.copyFrom()及传递给客户端的呢?

  • 当IPC调用来到服务进程时调用到IWindowSession.Stub.onTransact()函数,在该函数中会新建一个Surface对象。可以看到客户端的调用并没有传入在ViewRootImpl中生成的Surface而是在WMS进程中每次新建一个Surface对象。

  • 调用完成具体的实现之后,此时这里的Surface对象已经做了copy操作是一个真正的实现。需要做的就是在通过IPC写入到Parcel给客户端使用。

  • 到客户端这里会使用ViewRootImpl中的Surface对象从Parcel中读取真正的实现Surface对象给自己赋值。

以上就是IPC为ViewRootImpl中的Surface赋值真正实现的过程。

阅读全文
0 0