赞
踩
本节探讨一下chromium中加载URL的流程,具体来说是从地址栏输入URL地址到通过URLRequest类请求http流的过程。
WebContents类数据结构如下:
BrowserContext类:保存浏览过程中所需要的上下文。其运行在UI线程中,所有方法均只能在UI线程中调用。
net::URLRequestContextGetter*GetRequestContext获取URL请求所需的URLRequestContext
ResourceContext* GetResourceContext() 获取资源加载时需要的数据
SiteInstance类:站点对象,具体实现类为SiteInstanceImpl。一个SiteInstance对象对应于相同域名段的站点实例,如www.baidu.com和zhidao.baidu.com,其站点为baidu.com。不同的域名段有不同的SiteInstance对象,
这些SiteInstance对象都在BrowsingInstance注册备案. SiteInstance对象采取引用计数的方式控制生命周期。
BrowsingInstance类:理论上与BrowserContext一一对应,维护浏览期间所产生的SiteInstance对象。
BrowsingInstance内部维护一个站点URL(如:baidu.com)到SiteInstance对象的映射,并提供注册/取消注册、查找的接口。相当于SiteInstance的cache对象。
BrowsingInstance对象为诸多SiteInstance对象所共享,同样采用引用计数的方式控制生命周期
WebContents类对应于一页面窗口
其结构图大致如下:
创建WebContents需要填充WebContents::CreateParam参数。在CreateParam参数中需要指定: BrowserContext对象、SiteInstance对象、routing_id(用于路由消息的发送目的地、initial_size指定初始大小、context暂时没用上。
WebContentsDelegate接口:用于截获WebContents的更改通知以及提供相关的定制功能
NavigationController接口:负责页面的导航逻辑:前进、后退、刷新等。其内部维护一个导航过的NavigationEntry列表
WebContentsView接口:抽象WebContents的view界面部分,其windows下最终的实现类为WebContentsViewWin
WebContentsViewDelegate类:用于定制网页界面的扩展功能,比如显示右键菜单、焦点管理、尺寸调整等。
此处直接从RenderViewHostImpl::Navigate方法下手,该方法通过ViewMsg_Navigate消息,将URL请求信息发送到render进程。Render进程中通过RenderViewImpl类的OnNavigate方法响应该请求,
该方法将URL请求信息封装成一个WebURLRequest对象,调用WebKit层WebFrameImpl对象的loadRequest方法。这里有必要简单介绍下几个关键类之间的关系:
RenderViewImpl派生自RenderView类,是Render进程中网页展示部分,对应于browser进程中的RenderViewHostImpl类,负责与browser进程进行IPC消息的通讯、对网页中的诸多行为进行响应。RenderViewImpl维护一个WebView对象,两者通过一个map对象一一映射。在WebView接口的实现类中,有一个Page成员,表示整个页面, Page类中又有一个或多个Frame对象,至少有一个主Frame。WebFrame接口应该是Page中主Frame的public访问代理,其关联操作发生在WebViewImpl类的initializeMainFrame方法里。言归正传,WebFrameImpl的loadRequest方法最终会将请求转给FrameLoader的load方法,
FrameLoader是Frame的加载器。FrameLoader会将该请求委派给内部DocumentLoader成员的startLoadingMainResource方法来处理,再往下探讨之前,先把类之间的结构关系梳理一下:
DocumentLoader类:做为FrameLoader的成员,负责Document的加载。
ResourceFetcher类:资源提取器,相当于Resource的工厂类,负责创建不同的资源类型的Resource封装。比如Image资源对应的是ImageResource封装类,Script对应的是ScriptResource封装类。在这里DocumentLoader调用ResourceFetcher的fetchMainResource方法加载Document资源, 创建的封装类为RawResource,创建完成后调用Resource的load方法,内部创建ResourceLoader类来执行具体的加载行为。
分析到ResourceLoader类,方有拨开云雾见日月的感觉,该类内部维护一个WebURLLoader接口,顾名思义,这才是真正执行URL加载的地方,不过只是个抽象接口,隶属WebKit的public接口部分,与平台相关,chromium对此接口有自己的实现,位于webkit_glue层 的WebURLLoaderImpl实现WebURLLoader接口,相关类结构如下:
IPCResourceLoaderBridge将URL请求任务封装成ResourceHostMsg_RequestResource
消息发送到browser进程,由browser进程请求URL数据。
自此,URL请求消息由browser进程抛到render进程,之后绕一大圈又回到browser进程执行任务, 路由过程中将页面的框架搭建起来, 之后由browser进程的URLRequest请求到的网络数据发送到render进程所做的解析操作都是对页面框架的添砖加瓦。
接下来分析一下browser进程对render进程抛送过来的URL请求的处理。
在ResourceDispatcherHostImpl类的OnRequestResource方法对render进程发送过来的ResourceHostMsg_RequestResource消息进行响应,相关类结构如下:
每收到一个URL请求, ResourceDispatcherHostImpl会创建一个ResourceLoader对象来承接URL的加载任务, ResourceLoader封装URLRequest类的使用,并将请求过程中的相关事件和数据分派到ResourceHandler链中。ResourceHandler链中的AsyncResourceHandler类负责将请求事件和数据封装消息发送到render进程中。Render进程ResourceDispatcher类来响应这些消息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。