继续上一次分析到类WebContents的Navigate函数,在这个函数里通过参数entry传送入来,这样它只需要根据这个参数去下载网页回来显示,应就可以了吧,但到底是怎么样工作的呢?这需要深入去分析它,才知道它是什么样的结果。
#001
#002 bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
从渲染显示管理器里获取当前连接渲染显示对象。
#003 RenderViewHost* dest_render_view_host = render_manager_.Navigate(entry);
#004
设置开始下载计时的时钟。
#005 // Used for page load time metrics.
#006 current_load_start_ = TimeTicks::Now();
#007
在渲染显示对象里进行浏览处理。
#008 // Navigate in the desired RenderViewHost
#009 dest_render_view_host->NavigateToEntry(entry, reload);
#010
#011 if (entry.page_id() == -1) {
#012 // HACK!! This code suppresses javascript: URLs from being added to
#013 // session history, which is what we want to do for javascript: URLs that
#014 // do not generate content. What we really need is a message from the
#015 // renderer telling us that a new page was not created. The same message
#016 // could be used for mailto: URLs and the like.
#017 if (entry.url().SchemeIs("javascript"))
#018 return false;
#019 }
#020
判断是否重新加载旧的连接处理。
#021 if (reload && !profile()->IsOffTheRecord()) {
#022 HistoryService* history =
#023 profile()->GetHistoryService(Profile::IMPLICIT_ACCESS);
#024 if (history)
#025 history->SetFavIconOutOfDateForPage(entry.url());
#026 }
#027
#028 return true;
#029 }
在这个函数最主要的工作,就是调用类RenderViewHost函数NavigateToEntry,这个函数的代码如下:
#001 void RenderViewHost::NavigateToEntry(const NavigationEntry& entry,
#002 bool is_reload) {
创建浏览参数。
#003 ViewMsg_Navigate_Params params;
#004 MakeNavigateParams(entry, is_reload, ¶ms);
#005
授权渲染进程可以显示这个连接。
#006 RendererSecurityPolicy::GetInstance()->GrantRequestURL(
#007 process()->host_id(), params.url);
#008
发送浏览下载连接参数给进程处理。
#009 DoNavigate(new ViewMsg_Navigate(routing_id_, params));
#010
更新列表计数。
#011 UpdateBackForwardListCount();
#012 }
在这个函数里,主要创建浏览参数,然后调用函数DoNavigate来发送一个消息ViewMsg_Navigate给RHV进程,在UpdateBackForwardListCount函数里也发送一个消息ViewMsg_UpdateBackForwardListCount给RHV进程。
继续分析函数DoNavigate:
#001 void RenderViewHost::DoNavigate(ViewMsg_Navigate* nav_message) {
#002 // Only send the message if we aren't suspended at the start of a cross-site
#003 // request.
如果已经挂起,就开始重新复位这个消息。
#004 if (navigations_suspended_) {
#005 // Shouldn't be possible to have a second navigation while suspended, since
#006 // navigations will only be suspended during a cross-site request. If a
#007 // second navigation occurs, WebContents will cancel this pending RVH
#008 // create a new pending RVH.
#009 DCHECK(!suspended_nav_message_.get());
#010 suspended_nav_message_.reset(nav_message);
#011 } else {
或者直接发送这个消息出去。
#012 Send(nav_message);
#013 }
#014 }
函数UpdateBackForwardListCount的代码如下:
#001 void RenderViewHost::UpdateBackForwardListCount() {
#002 int back_list_count, forward_list_count;
#003 delegate_->GetHistoryListCount(&back_list_count, &forward_list_count);
#004 Send(new ViewMsg_UpdateBackForwardListCount(
#005 routing_id_, back_list_count, forward_list_count));
#006 }
可以从函数DoNavigate和UpdateBackForwardListCount里看到,最后都把这些事件变成消息,通过类RenderProcessHost来发送出去,主要使用IPC的通讯机制。具体是怎么样通讯的呢?下一次再来分析它。