在介绍Framework相关模块的内容时,相比于把详细的流程代码贴出来,我更愿意把模块的层次结构、各个组件的关联以图形的形式呈现出来。所以按照国际惯例,直接上图,下面就开始介绍ViewrootImpl,SurfaceView(GlSurfaceView 本身继承自SurfaceView,没有太多可介绍的,所以没有画出来),TextureView。
1、ViewRootImpl
这个类是view的管理者,真正的根节点是mView(DecorView实例),这里将ViewRootImpl画出来,更能清楚显示出ui的结构和相关模块。如图中的WindowInputEventReceiver,就是负责接收InputManager上报上来的input事件。Surface是BufferQueue的producer端,渲染后的buffer通过它送到surfaceflinger去显示。IwindowSession和IWindow.Stub是和WindowManagerService打交道,一个充当binder的proxy端,另一个充当server端,这样就可以实现双向通信。除了和WindowManagerService有联系,还和很多其他模块相关联,这里就不一一画出来了,
1)input 事件上报
在InputManagerService中有两个线程,InputReaderThread负责从EventHub读取Event,经过处理后,交给InputDispatcherThread上报给上层,忽略其他Service对特殊事件的处理,可以简单的认为InputDispatcherThread将input事件给到了Activity(应用)。
InputReader从input driver读到input evnet后,会经过多个模块的处理,其中InputMapper的处理最为负责,有兴趣可以看一下源码,然后丢给QueuedInputListener去notify。
void QueuedInputListener::flush() {
size_t count = mArgsQueue.size();
for (size_t i = 0; i < count; i++) {
NotifyArgs* args = mArgsQueue[i];
args->notify(mInnerListener);
delete args;
}
mArgsQueue.clear();
}
有些同学可能不理解mInnerListener 是什么,这个其实是InputDispatcher实例,所以InputReader读到的事件,经过各种处理和包装,到这里就丢到InputDispatcher的队列里面去了,接下来就由InputDispatcher (InputDispatcherThread线程)将事件给到应用。这里是一个跨进程的数据传输,这里用到的是socket方式,InputChannel就是对socket两端读写操作的封装。
status_t InputChannel::sendMessage(const InputMessage* msg) {
size_t msgLength = msg->size();
ssize_t nWrite;
do {
nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_