谷歌浏览器的源码分析(21)
上一次说到类RenderThread和类RenderView把消息处理,那么这两个类是怎么样处理消息的呢?又是怎么样处理浏览的消息呢?现在就带着这两个问题去分析它的源码,理解它处理消息的方法。类RenderThread处理消息的代码如下:
#001 void RenderThread::OnMessageReceived(const IPC::Message& msg) {
#002 // NOTE: We could subclass router_ to intercept OnControlMessageReceived, but
#003 // it seems simpler to just process any control messages that we care about
#004 // up-front and then send the rest of the messages onto router_.
#005
下面判断是控制消息,如果是控制消息就在本类里处理,否则就分发到别的地方处理,主要是转到类RenderView处理。
#006 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
#007 IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
#008 IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
#009 IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
#010 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
#011 IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
#012 IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
#013 OnGetCacheResourceStats)
#014 // send the rest to the router
#015 IPC_MESSAGE_UNHANDLED(router_.OnMessageReceived(msg))
#016 IPC_END_MESSAGE_MAP()
#017 } else {
这里是分发消息到别的地方处理。
#018 router_.OnMessageReceived(msg);
#019 }
#020 }
在浏览器里,消息分为两大类:控制消息和路由消息。像使用IPC_MESSAGE_CONTROL宏定义的消息,就是控制消息;使用IPC_MESSAGE_ROUTED宏定义的消息,就是路由消息。
路由消息分发是由类MessageRouter来负责的,主要处理的代码如下:
#001
#002 void MessageRouter::OnMessageReceived(const IPC::Message& msg) {
#003 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
#004 OnControlMessageReceived(msg);
#005 } else {
#006 RouteMessage(msg);
#007 }
#008 }
在这里又分为MSG_ROUTING_CONTROL消息和其它路由消息,再一次通过函数RouteMessage分发之后,如下:
#001 bool MessageRouter::RouteMessage(const IPC::Message& msg) {
#002 IPC::Channel::Listener* listener = routes_.Lookup(msg.routing_id());
#003 if (!listener)
#004 return false;
#005
#006 listener->OnMessageReceived(msg);
#007 return true;
#008 }
上面这个函数里又把消息通过发送到listener里去,其实listener是根据消息的目标routing_id来选择的,那么就是说它是选择发送到不同的窗口里去,因为每个TAB一个窗口。消息经过这样的处理之后,就到达了终点地--- RenderView::OnMessageReceived函数。下一次再来分析RenderView::OnMessageReceived函数的代码和后继处理。