WebKit引擎介绍.doc_第1页
WebKit引擎介绍.doc_第2页
WebKit引擎介绍.doc_第3页
WebKit引擎介绍.doc_第4页
WebKit引擎介绍.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

WebKit引擎入门介绍1 WebKit简介31.1 简介31.2 WebKit主要特点31.2.1 引擎31.2.2 开源31.2.3高性能41.2.4 可移植性41.2.5 兼容性41.2.6 遵守标准41.2.7 安全41.3 WebKit主要组成41.3.1 体系结构52 WebCore介绍52.1 WebCore目录结构52.2 Http请求在WebCore中的主要流程62.2.1 工作流程62.2.2 处理流程83 WebKit的DOM分析103.1 DOM原理103.1.1 DocView 模型103.2 DOM解析基本算法113.2.1 基本算法思想114 WebKit的Ports介绍154.1 Port概述154.2 WebKit Port移植实现分析164.2.1 WebCore交互接口164.2.2 连接模块loader164.2.3 显示模块WebView和WebFrame164.2.4 Android中对Port移植方面的实现174.2.5 小结175 WebKit的JavascriptCore介绍185.1 JavaScriptCore实现特点185.2 JavaScriptCore目录的内容185.3 JavaScriptCore与WebCore交互196 WebKit For Android196.1 WebKit模块目录结构196.2 Java层框架226.2.1 主要类描述226.2.2 数据载入器的设计236.3 C层框架246.4 WebView操作分析256.4.1 WebKit模块初始化256.4.2 数据载入276.5 刷新绘制281 WebKit简介1.1 简介WebKit 的前身是 KDE 小组的 KHTML。Apple 将 KHTML 发扬光大,推出了装备 KHTML 改进型的 WebKit 引擎的浏览器Safari,获得了非常好的反响。WebKit 引擎比 Gecko 引擎更受程序员欢迎的原因,除了其引擎的高效稳定,兼容性好外,其源码结构清晰,易于维护,是一个重要的原因。现在浏览器的内核引擎,基本上是三分天下:Trident: IE 以Trident 作为内核引擎。Gecko: Firefox 是基于 Gecko 开发。WebKit: Safari, Google Chrome 基于 Webkit 开发。还有一个Presto:Opera,任天堂DS浏览器,发展也良好。WebKit 内核在手机上的应用十分广泛,例如 Google 的手机Gphone、 Apple 的 iPhone, Nokias Series 60 browser 等所使用的 Browser 内核引擎,都是基于 WebKit。1.2 WebKit主要特点1.2.1 引擎该项目的主要重点是内容部署在万维网上的,基于标准的技术,如HTML,CSS , JavaScript和DOM中。并能够嵌入WebKit在其他应用程序中,并用它作为一般用途的显示和交互引擎。1.2.2 开源WebKit继续自由使用的两个开源协议LGPL和BSD,在Webkit中,WebCore和JavaScriptCore是LGPL,其余是BSD授权。1.2.3高性能维持和改善的速度和内存使用是一个重要的目标。随着网页内容越来越丰富,越来越复杂,作为网络浏览器上运行的更有限的设备,需要提升性能,加快浏览速度。1.2.4 可移植性WebKit 移植到各种各样的台式机、移动、嵌入式平台和其他平台。WebKit 提供必要的基础设施,并酌情提供友好嵌入的API。1.2.5 兼容性用户浏览网页,兼容现有的网站是必不可少的。WebKit致力于维护和改善兼容现有的网络内容,利用回归测试,以保持WebKit的兼容性。1.2.6 遵守标准WebKit的目标是遵守有关的Web标准,并支持新的标准。1.2.7 安全保护用户安全的行为是至关重要的。迅速修复安全问题,以保护用户系统和维护他们对WebKit的信任。1.3 WebKit主要组成WebKit 主要包括三个部分WebCore、JavascriptCore 及Ports部分。WebKit 专注的核心部分主要是:分析Html,Javascript 的解析和布局渲染技术。分别在由WebCore/html,JavascriptCore 和WebCore/rendering来完成。1.3.1 体系结构WebKit的体系结构如下图:2 WebCore介绍2.1 WebCore目录结构根据源代码目录结构,WebCore目录主要包括如下:bindings:将Dom Binding 给JavascriptCore 方面的代码,同时包含依据idl接口描述文件,自动生成对应于JavascriptCore 的Binding 实现的脚本等内容;bridge:主要包含NPPlugin 方面的接口访问等内容;css:主要包括与css 方面相关的内容,如解析不同css 规则的定义与实现、css Binding 给JS的接口定义等内容;dom:主要包括dom方面相关的内容,如不同dom元素的定义与实现、dom Binding给JS的接口定义等内容;html:关于html 方面相关的内容,如不同html 元素的定义与实现、HTMLTokenizer 及HTMLParser等内容。loader:主要包括装载资源,如html页面、css、js 及image等方面内容;page:主要包括描述一个Web 页面所涉及的内容如page、frame、frameview、frametree、setting、history、chrome、chromeclient等内容;rendering:主要包括如何使用样式,组织布局、显示html 元素等方面内容;plugins:主要包括浏览端如何实现NPPlugin 方面的内容;svg:主要包括与svg 方面相关的内容;xml:主要包括与xml 方面相关的内容,如xml parser、XPath、XSLT等;platform:主要包括与不同平台或外部库相关的内容如graphics(图形输出方面)、network(网络处理方面)、image-decoders(解析不同图片格式方面)等。2.2 Http请求在WebCore中的主要流程2.2.1 工作流程如下图所示:流程解析:1. 用户向Shell发出页面请求后,页面的URL 或本地文件名被发送到Shell;2. Shell 调用IO组件,把URL 传达到IO组件;3. IO组件使用HTTP 协议或再调用本地IO获取HTML/XHTML源数据,返回Shell;4. Shell 把IO 返回的HTML/XHTML source 提交HTML/XHTML分析器;5. HTML/XHTML分析器分析HTML/XHTML代码,构建一棵DOM 树,树根为HTMLDocument;6. 通过DOM 树,生成Render 树。 Render树,简单的说来,它是对DOM 树更进一步的描述,其描述的内容主要与布局渲染等CSS相关属性如left、 top、width、height、color、font等有关,因为不同的DOM 树结点可能会有不同的布局渲染属性,甚至布局时会按照标准动态生成一些 匿名节点,所以为了更加方便的描述布局及渲染,WebKit内核又生成一颗Render 树来描述DOM 树的布局渲染等特性,当然DOM 树与Render 树 不是一一对应,但可以相互关联;7. 布局管理器layout对应控件。当布局管理器对可视化元素指派好位置和大小后,可视化元素必须要严格遵守布局管理器给它分配的位置和大小,不能擅自更改,相应控件根据自己的属性进行表现自己了,如背景,外形等。2.2.2 处理流程流程描述:通过向服务器发送请求服务器通过请求,发给客户端html的内容浏览器通过W3C 规范,把接受到的内容解析成DOM 树,在解析DOM 树的同时会生成对应的Render 树。布局管理器通过Render 树,开始布局。这个是一个动态的过程,DOM在这个时候会继续向服务器申请自己需要的东西, 比如CSS,JavaScript,图片等,然后布局器动态的加载或布局,这样可以改善用户的体验,最后把整个网页render出来。3 WebKit的DOM分析3.1 DOM原理3.1.1 DocView 模型DocView 模型包括:网页标识、网页类型、内容类别、标题、关键词、摘要、正文、相关链接等要素。其中正文和相关链接要素属于网页的内容数据,而其他 6 项则属于网页的元数据。网页标识:对 Web 上网页的唯一性标识,在 DocView 模型中使用网页的URL 作为网页标识。网页类型:主题网页(topic)、Hub 网页(hub)、图片网页(pic)。其中,有主题网页是指网页中通过文字描述了一件或多件事物,是有一定主题的。如一张具体的新闻网页就是典型的有主题网页。Hub 网页是指专门用来提供网页导向的网页,因 而是超链聚集的网页。如门户网站的首页就是典型的 Hub 网页。图片网页是指网页的内容是通过图片的形式体现的,其中文字很少,仅是对图片的一个说明。如某个机构包含图片的人员介绍网页就是典型的图片网页。内容类别是从语义上对网页的内容进行分类,它是计算机获取网页语义信息的一个直接手段,在 Web 上的研究领域中有着广泛的使用。它是通过特定的分类器对网页内容分类得到的,依赖于一定的分类体系。标题、关键词和摘要是概括描述 Web 文档内容的重要的元数据,对于 Web 信息检索等领域的工作有非常重要的作用。正文:原始网页中真正描述主题的部分,因此,在某些具体应用中用正文代替原始网页更为合理。相关链接是指在本网页中指向与正文内容相关的网页的链接,而非广告等噪音链接。将正文和相关超链重新组合就得到了净化后的网页。超链相关的标签是 HTML 网页区别于传统文本的明显的特点之一,表示着网页间的关系,因此整理出超链标签并作合理的分析可以挖掘出网页间的 内容相关性信息。目前,有很多构造标签树的工具(如:W3C HTML lexicalanalyzerW3C,1997),它们各有特点,W3C HTML lexical analyzer有很强的通用性,适合各种标识语言;HTML Tidy 则能够自动发现并修正标签的错误。3.2 DOM解析基本算法3.2.1 基本算法思想1. Html 中每个tag 都是作为树中的一个节点存在的,每个tag都属于树中的某一层。2. 辅助数据结构:栈(stack)、List、HashTable。其中HashTablei(i 属于int 类型)是一个List,用于临时存储第i 层子Tag。3. 顺序扫描Html 文本,当遇到”AZ”这样的标志,表示可能是一个Tag,调用GetTag()函数对此段代码进行解析,解析出Tag 名,Tag属性等等。如果返回值不为空,那么将返回值入栈。并且记录次tag的开始位置。4. 遇到这样的标志,表示可能是某个Tag的结束。解析出此结束标志的Tag 名。如果在栈中找到与此结束标志名同名的元素(此元素属于栈中第iLevel 层),那么表示找到匹配的Tag。则Tag出栈,将HashTableiLevel+1到HashTablemaxLevel中的所有元素取出作为此Tag 的子节点。放入第HashTable iLevel中。并记录Tag的结束位置。5. 对于xxx之间的字符串xxx,将其作为特殊的HtmlTextTag 处理。出栈,和入栈操作与普通Tag 类似。6. 当栈为空的时候表示最后一次出栈的Tag 为根节点。伪代码:public void Parse()char ch = GetCurrentChar(); /取第一个字符while (!Eof() if (ch = = A) & (ch 0) /将文本作为一个普通Tag入栈Stack.Push(new HtmlTextTag(m_CurrentText);tag.BeginPos = iBeginPos; /记录此Tag的开始位置Stack.Push(tag); /把Tag入栈ch = GetCurrentChar();if (ch = /)/可能是结束标签tagName = GetTagName();/从上到下查看Stack,如果Tag中存在if (FindInStack(tagName)/在栈中找到名为tagName的元素,则把找到的元素出栈PopTag(tagName);else/xxx之间的文本xxx,这里将作为TextTag来处理m_CurrentText.Append(GetCurrentChar();/继续处理下一个字符ch = MoveNext();/解析完成以后,如果栈不空,那么把元素出栈,并把最后一次出栈的元素作为根if (Stack.Count 0)HtmlTag tag = null;while (Stack.Count 0)tag = Stack.Pop();PopTag(tag);/最后一个元素作为根元素if (tag != null)m_listRoot.Add(tag);private void PopTag(HtmlTag tag) int iLevel = Stack.Count;/找到了元素,把iLevel到m_IMaxLevel中所有的元素按照全部作为tag的子元素for (int i = iLevel + 1; i m_iMaxLevel; i+)for (j = 0; j HashTablei.Count; j+)tag.Children.Add(HashTableij);/表示栈已经为空,那么最后一次出栈的tag将作为根if (Stack.Count = 0)m_listRoot.Add(tag);private void PopTag(string tagName)/* 元素出栈的时候,首先需要把当前已经存在了的HtmlTextTag入栈* 比如:文本段1文本段2文本段3182.* 在Parse中,当解析出入栈前,需要先把文本段1入栈* 在这里,解析出了结束标志* 那么首先需要把文本段2入栈。* 解析出则需要把文本段3入栈。* 这样才能够保证文本段1和文本段3成为的子节点,* 而文本段2作为的子节点*/if (m_CurrentText.Lenght 0)/将文本作为一个普通Tag入栈Stack.Push(new HtmlTextTag(m_CurrentText);HtmlTag tag = Stack.Pop(); /元素出栈int iLevel = Stack.Count; /记录栈元素数while (tag.Name != tagName) /将tag放入第iLevel层的List中HashTableiLevel.Add(tag);tag = Stack.Pop();iLevel = Stack.Count;/元素出栈后续处理PopTag(tag);private HtmlTag GetTag()/则表示是注释if (如果发现是 !-开头的元素) SkipComment();HtmlTag tag = new HtmlTag();tag.Name = GetTagName();/这里的Attribute我将其作为HashTable类型,Hash属性名=属性值tag.Attribute = GetTagAttribute();return tag;4 WebKit的Ports介绍4.1 Port概述WebKit Port 方面的内容很广,可将不同的图形库、网络库与WebCore集成,提供不同的Port接口供外部程序使用等,例如同样在windows 平台上可以运行的Google Chrome 和Safari 就是针对WebKit在不同平台的移植。Port 方面的主要内容是提供不同的Port 接口供外部程序使用以及如何与外部程序交互。WebKit 中的其它两部分WebCore、 Javascript 实现,从逻辑上讲是不直接提供接口给外部程序使用的,同时WebKit为了完成浏览器的核心功能,也需要从外部程序中通过Port 接口的方式获取一些支持。WebKit 作为一个相对独立的整体,它与外部程序之间的交互也就有一组相对固定的接口来定义及维护它们之间的关系,它们之间的关系与插件跟浏览器引擎之间的关系完全类似,接口相当一组协议,有的是由WebKit 来实现,而供外部程序调用,有的的正好相反。通过前面的了解我们知道WebKit的主要功能集中在分析Html、渲染布局Web 内容以及Javascript 实现方面等,而这些Web 内容显示在哪个窗口及消息处理的启动循环等都需要由外部程序来提供,这一切都由Ports来完成。4.2 WebKit Port移植实现分析4.2.1 WebCore交互接口在 WebKit源代码目录结构中WebKit目录下分别包含gtk、mac、qt、win、wx 目录,其分别对应不同的Port 移植方式,在每一个目录下面 都包括WebCoreSupport 目录,而在不同的WebCoreSupport目录下分别包含有对类接口 WebCore:ChromeClient 、WebCore:ContextMenuClient 、WebCore:DragClient 、WebCore:EditorClient 、WebCore:FrameLoaderClient 、WebCore:InspectorClient 等的实现,它们代表外部程序提供给WebKit 内部使用的接口实现,其中WebCore:ChromeClient、WebCore:FrameLoaderClient非常重要。初步了解其接口定义能基本了解其对应的含义,这些接口往往需要由Port 移植部分来提供实现,往往由WebKit内部根据一定的条件来调用。4.2.2 连接模块loader对于WebCore中page/loader等类提供对应port实现的支持如EVentHandlerWin.cpp 、FrameLoaderWin.cpp 、DocumentLoaderWin.cpp、DocumentLoaderWin.cpp、WidgetWin.cpp、KeyEventWin.cpp等.Loader 是在WebKit 里面一个很重要的连接器,通过loader 发起IO下载网页,再通过loader发起解析,已经最后的渲染功能。4.2.3 显示模块WebView和WebFrameWebView 及WebFrame 主要功能是方便外部程序嵌入WebKit不同的Port 移植对WebView 及WebFrame的定义及实现有所不同,但其与WebCore中的Page、Frame 之间的关系图描述相一致。具体关于WebView、WebFrame的定义与实现,特别是初始化时的动作可根据不同的Port 移植而有所不同,同时初始化时会将上面提到的WebCorePort 接口实现告诉WebKit内部4.2.4 Android中对Port移植方面的实现Android实现有点特殊,由于Andriod 将WebKit 以一个Java 类接口的方式提供给Java 环境使用(不像Chrome、Safari 等都是将WebKit 以 一个C+动态或静态库的方式供C/C+外部程序调用),这样WebKit 内部与外部即JavaVM 的交互(如上面提到的ChromeClient、FrameLoaderClient 接口实现)需要一个Bridge 类来协调处理,同时WebView、WebFrame 接口绑定给JavaVM 的jni 接口实现也需要通过这个Bridge 来支持协调处理。具体可详细参考android源码代码中WebCoreplatformandroid目录下的源文件。4.2.5 小结通过进一步了解WebCore Port 接口及其实现,可以加深这样一个认识。如果从MVC的角度来看整个基于WebKit的浏览器,WebKit 的Port 部分相当于V 部分,它提供显示页面内容及其辅助信息(如提示状态)的场所(即原生窗口)以及控制该显示场所的状态变化及消息响应(如改变大小、 鼠标移动等);而M 部分往往由WebCore来实现,至于WebCore如何组织DOM则往往由htmlparser部分根据DOM 定义来组织,如何在提 供的显示场所显示Web 内容则往往由WebCore 中的layout 部分来实现,其中充分利用了Css 定义来布局显示该显示的内容。一旦涉及控制或动态处理往往由Port 部分发起而由Javascript 脚本来实现处理,其任务由JavascriptCore或V8 (JS解析Core)来完成。一般说来新打开一个页面,Port 部分需要提供一个主显示场所(即原生窗口),如果页面中含有iframe 标签,则需要在主显示场所内创建一个子显示场所,以显示iframe 标签对应src 的内容。如果页面中含有embed/object 等插件标签同样往往也需要在主显示场所内创建一个子显示场所(除非windowless),以交由插件实现在提供的显示场所中显示内容。特别需要说明的是我们通常看到的页面表单元素input textfield、textArea、button、radiobutton等往往不像window 图形库中的按钮、菜单、输入框等会对应一个原生窗口,页面中的表单元素在一个显示场所(即原生窗口)中完全是利用Css 等通过layout 方式来达到我们所看到的类似原生按钮、输入框、列表框、滚动条等效果,其中 特别是能准确定位元素大小、设置focus、光标显示、响应事件等,这充分的说明了浏览器引擎内部布局部分的威力所在。 从另外一个角度来看,一个页面一般说来(除非遇到iframe 或插件需要另外提供一块子画布)相当于一块画布,浏览器引擎能在其精确的位置绘制不同颜色的文字、图片、图标 等,同时根据当前的鼠标及一个模拟的输入提示光标位置,接收键盘输入操作。页面中的绝大多数元素与原生的窗口元素几乎没有关联,完全通过组合、布局、准确定位来处理一切。5 WebKit的JavascriptCore介绍在WebKit中其Javascript实现,同样相当于一个符合ECMAScript标准的动态库,其往往依附于浏览器引擎,由浏览器引擎来提供运行环境,并控制或发起javascript实现进行编译、解析执行脚本、垃圾回收等,同样需提供对浏览器引擎扩展的支持如Dom Binding等;5.1 JavaScriptCore实现特点相对于其他的Javascript实现,JavaScriptCore提出了虚拟机的概念,在编译脚本时生成高效的bytecode,bytecode统一在一个虚拟机的环境中执行。而其高效的虚拟机实现常称为SquirrelFish,通过Announcing SquirrelFish、Introducing SquirrelFish Extreme可更进一步了解关于SquirrelFish的相关内容5.2 JavaScriptCore目录的内容1. assembler:jit编译中间码用到的汇编程序2. bytecode:中间码相关的类和定义3. 生成中间码的类实现,实际上是编译Node类4 .interpreter:用来执行js的类,实际上就是执行CodeBlock5. jit:执行jit汇编程序的类6. parser:解析js用到的词法分析类,语法分析bison文件和Node类结构7. runtime:是js的执行环境中自带的类8. wtf:是WebCor和JavaScriptCore用到的基础类5.3 JavaScriptCore与WebCore交互在WebCore:Frame的数据结构中包含数据成员KJSProxy* m_jscript,而在Chrome的代码中调整为JSBridge* m_jscript;,具体不同Javascript实现如何实现与WebCore的接口,需了解不同Javascript实现逻辑,如对Javascript实现逻辑及基本原理感兴趣,可具体参考其提供的api及sample等。6 WebKit For AndroidAndroid平台的WebKit模块由Java层和WebKit库两个部分组成,Java层负责与Android应用程序进行通信,而WebKit类库负责实际的网页排版处理。Java层和C层库之间通过JNI和Bridge相互调用,如下图所示:6.1 WebKit模块目录结构Java层(根目录devicejavaandroidandroidwebkit)包含41个类:1. BrowserFrame.java: BrowserFrame对象是对WebCore库中的Frame对象的Java层封装,用于创建WebCore中定义的Frame,及为该Frame对象提供Java层回调方法。2. ByteArrayBuilder.java: ByteArrayBuilder辅助对象,用于byte块链表的处理。3. CachLoader.java: URL Cache载入器对象,该对象实现StreadLoader抽象基类,用于通过CacheResult对象载入内容数据。4. CacheManager.java: Cache管理对象,负责Java层Cache对象管理。5. CacheSyncManager.java: Cache同步管理对象,负责同步RAM和FLASH之间的浏览器Cache数据。实际的物理数据操作在WebSyncManager对象中完成。6. CallbackProxy.java: 该对象是用于处理WebCore与UI线程消息的代理类。当有Web事件产生时WebCore线程会调用该回调代理类,代理类会通过消息的方式通知UI线程,并且调用设置的客户对象的回调函数。7. CellList.java: CellList定义图片集合中的Cell,管理Cell图片的绘制、状态改变以及索引。8. CookieManager.java: 根据RFC2109规范,管理cookies。9. CookieSyncManager.java: Cookies同步管理对象,该对象负责同步RAM和Flash之间的Cookies数据。实际的物理数据操作在基类WebSyncManager中完成。10. DataLoader.java: 数据载入器对象,用于载入网页数据。11. DateSorter.java: 尚未使用。12. DownloadListener.java: 下载侦听器接口。13. DownloadManagerCore.java: 下载管理器对象,管理下载列表。该对象运行在WebKit的线程中,通过CallbackProxy对象与UI线程交互。14. FileLoader.java: 文件载入器,将文件数据载入到Frame中。15. FrameLoader.java: Frame载入器,用于载入网页Frame数据littlefe。16. HttpAuthHandler.java: Http认证处理对象,该对象会作为参数传递给BrowserCallback.displayHttpAuthDialog方法,与用户交互。17. HttpDataTime.java: 该对象是处理HTTP日期的辅助对象。18. JsConfirmResult.java: Js确认请求对象。19. JsPromptResult.java: Js结果提示对象,用于向用户提示Javascript运行结果。20. JsResult.java: Js结果对象,用于用户交互。21. JWebCoreJavaBridge.java: 用Java与WebCore库中Timer和Cookies对象交互的桥接代码。22. LoadListener.java: 载入器侦听器,用于处理载入器侦听消息。23. Network.java: 该对象封装网络连接逻辑,为调用者提供更为高级的网络连接接口。24. PanZoom.java: 用于处理图片缩放、移动等操作。25. PanZoomCellList.java: 用于保存移动、缩放图片的Cell。26. PerfChecker.java: 用于效率测试的功能对象。27. SslErrorHandler.java: 用于处理SSL错误消息。28. StreamLoader.java: StreamLoader抽象类是所有内容载入器对象的基类。该类是通过消息方式控制的状态机,用于将数据载入到Frame中。29. TextDialog.java: 用于处理html中文本区域叠加情况,可以使用标准的文本编辑而定义的特殊EditText控件。30. URLUtil.java: URL处理功能函数,用于编码、解码URL字符串,以及提供附加的URL类型分析功能。31. WebBackForwardList.java: 该对象包含WebView对象中显示的历史数据。32. WebBackForwardListClient.java :浏览历史处理的客户接口类,所有需要接收浏览历史改变的类都需要实现该接口。33. WebChromeClient.java: Chrome客户基类,Chrome客户对象在浏览器文档标题、进度条、图标改变时候会得到通知。34. WebHistoryItem.java: 该对象用于保存一条网页历史数据。35. WebIconDataBase.java: 图表数据库管理对象,所有的WebView均请求相同的图标数据库对象。36. WebSettings.java: WebView的管理设置数据,该对象数据是通过JNI接口从底层获取。37. WebSyncManager.java: 数据同步对象,用于RAM数据和FLASH数据的同步操作。38. WebView.java: Web视图对象,用于基本的网页数据载入、显示等UI操作。39. WebViewClient.java: Web视图客户对象,在Web视图中有事件产生时,该对象可以获得通知。40. WebViewCore.java: 该对象对WebCore库进行封装,将UI线程中的数据请求发送给WebCore处理,并通过CallbackProxy的方式,通过消息通知UI线程数据处理结果。41. WebViewDatabase.java: 该对象使用SQLiteDatabase为WebCore模块提供数据存取操作。6.2 Java层框架6.2.1 主要类描述1. WebViewWebView类是WebKit模块Java层的视图类,所有需要使用Web浏览功能的Android应用程序都要创建该视图对象显示和处理请求的网络资源。目前,WebKit模块支持HTTP、HTTPS、FTP以及javascript请求。WebView作为应用程序的UI接口,为用户提供了一系列的网页浏览、用户交互接口,客户程序通过这些接口访问WebKit核心代码。2. WebViewDatabaseWebViewDatabase是WebKit模块中针对SQLiteDatabase对象的封装,用于存储和获取运行时浏览器保存的缓冲数据、历史访问数据、浏览器配置数据等。该对象是一个单实例对象,通过getInstance方法获取WebViewDatabase的实例。WebViewDatabase是WebKit模块中的内部对象,仅供WebKit框架内部使用。3. WebViewCoreWebViewCore类是Java层与C层WebKit核心库的交互类,客户程序调用WebView的网页浏览相关操作会转发给BrowserFrame对象。当WebKit核心库完成实际的数据分析和处理后会回调WebViweCore中定义的一系列JNI接口,这些接口会通过CallbackProxy将相关事件通知相应的UI对象。4. CallbackProxyCallbackProxy是一个代理类,用于UI线程和WebCore线程交互。该类定义了一系列与用户相关的通知方法,当WebCore完成相应的数据处理,则会调用CallbackProxy类中对应的方法,这些方法通过消息方式间接调用相应处理对象的处理方法。5. BrowserFrameBrowserFrame类负责URL资源的载入、访问历史的维护、数据缓存等操作,该类会通过JNI接口直接与WebKit C层库交互。6. JWebCoreJavaBridge该类为Java层WebKit代码提供与C层WebKit核心部分的Timer和Cookies操作相关的方法。7. DownloadManagerCore下载管理核心类,该类负责管理网络资源下载,所有的Web下载操作均有该类同一管理。该类实例运行在WebKit线程当中,与UI线程的交互是通过调用CallbackProxy对象中相应的方法完成。8. WebSettings该对象描述了WEB浏览器访问相关的用户配置信息。9. DownloadListener下载侦听接口,如果客户代码实现该接口,则在下载开始、失败、挂起、完成等情况下,DownloadManagerCore对象会调用客户代码中实现的DownloadListener方法。10. WebBackForwardListWebBackForwarList对象维护着用户访问历史记录,该类为客户程序提供操作访问浏览器历史数据的相关方法。11. WebViewClientWebViewClient类定义了一系列事件方法,如果Android应用程序设置了WebViewClient派生对象,则在页面载入、资源载入、页面访问错误等情况发生时,该派生对象的相应方法会被调用。12. WebBackForwardListClientWebBackForwardListClient对象定义了对访问历史操作时可能产生的事件接口,当用户实现了该接口,则在操作访问历史时(访问历史移除、访问历史清空等)用户会得到通知。13. WebChromeClientWebChromeClient类定义了与浏览窗口修饰相关的事件。例如接收到Title、接收到Icon、进度变化时,WebChromeClient的相应方法会被调用。6.2.2 数据载入器的设计WebKit模块的Java部分框架中使用数据载入器来加载相应类型的数据,目前有CacheLoader、DataLoader以及FileLoader三类载入器,他们分别用于处理缓存数据、内存据,以及文件数据的载入操作。Java层(WebKit模块)所有的载入器都从StreamLoader继承(其父类为Handler),由于StreamLoader类的基类为Handler类,因此在构造载入器时,会开启一个事件处理线程,该线程负责实际的数据载入操作,而请求线程通过消息的方式驱动数据的载入。下图是数据载入器相关类的类图结构:StreamLoader类定义了4个不同的消息(MSG_STATUS、MSG_HEADERS、MSG_DATA、MSG_END),分别表示发送状态消息、发送消息头消息、发送数据消息以及数据发送完毕消息。该类提供了2个抽象保护方法以及一个共有方法:setupStreamAndSendStatus保护方法主要是用于构造与通信协议相关的数据流,以及向LoadListener发送状态;buildHeaders方法是向子类提供构造特定协议消息头功能,所有载入器只有一个共有方法(load),因此当需要载入数据时,调用该方法即可。与数据载入流程相关的类还有LoaderListener以及BrowserFrame,当数据载入事件发生时,WebKit C库会更新载入进度,并且会通知BrowserFrame,BroserFrame接收到进度条变更事件后会通过CallbackProxy对象,通知View类进度条数据变更。6.3 C层框架略过。6.4 WebView操作分析6.4.1 WebKit模块初始化Android SDK中提供了WebView类,该类为客户提供客户化浏览显示的功能,如果客户需要加入浏览器的支持,可将该类的实例或者派生类的实例作为视图,调用Activity类的setContentView显示给用户。当客户代码中生成第一次生成WebView对象时,会初始化WebKit库(包括Java层和C层两个部分),之后用户可以操作WebView对象完成网络或者本地资源的访问。WebView对象的生成主要涉及3个类CallbackProxy、WebViewCore以及WebViewDatabase。其中CallbackProxy对象为WebKit模块中UI线程和WebKit类库提供交互功能,WebViewCore是WebKit的核心层,负责与C层交互以及WebKit模块C层类库初始化,而WebViewDatabase为WebKit模块运行时缓存、数据存储提供支持。WebKit模块初始化流程如下: WebView实例化1. 创建CallbackProxy对象2. 创建WebViewCore对象3. 调用System.loadLibrary载入webcore相关类库(C层)4. 如果是第一次初始化WebViewCore对象,创建WebCoreTherad线程5. 创建EventHub对象,处理WebViewCore事件6. 获取WebIconDatabase对象实例7. 向WebCoreThread发送初始化消息 获取WebViewDatabase实例1. 调用System.loadLibrary方法载入webcore相关类库,该过程由Dalvik虚拟机完成,它会从动态链接库目录中寻找libWebCore.so类库,载入到内存中,并且调用WebKit初始化模块的JNI_OnLoad方法。WebKit模块的JNI_OnLoad方法中完成了如下初始化操作:a) 初始化framebridgeregister_android_webcore_framebridge初始化gFrameAndroidField静态变量,以及注册BrowserFrame类中的本地方法表。b) 初始化javabridgeregister_android_webcore_javabridge初始化gJavaBridge.mObject对象,以及注册JWebCoreJavaBridge类中的本地方法c) 初始化资源loaderregister_android_webcore_resource_loader初始化gResourceLoader静态变量,以及注册LoadListener类的本地方法d) 初始化webviewcoreregister_android_webkit_webviewcore初始化gWebCoreViewImplField静态变量,以及注册WebViewCore类的本地方法e) 初始化webhistoryregister_android_webkit_webhistory初始化gWebHistoryItem结构,以及注册WebBackForwardList和WebHistoryItem类的本地方法f) 初始化webicondatabaseregister_android_webkit_webicondatabase注册WebIconDatabase类的本地方法g) 初始化websettingsregister_android_webkit_websettings初始化gFieldIds静态变量,以及注册WebSettings类的本地方法h) 初始化webviewregister_android_webkit_webview初始化gWebViewNativeField静态变量,以及注册WebView类的本地方法2. WebCoreThread初始化,该初始化只在第一次创建WebViewCore对象时完成,当用户代码第一次生成WebView对象,会在初始化WebViewCore类时创建WebCoreThread线程,该线程负责处理WebCore初始化事件。此时WebViewCore构造函数会被阻塞,直到一个WebView初始化请求完毕时,会在WebCoreThread线程中唤醒。3. 创建EventStub对象,该对象处理WebView类的事件,当WebCore初始化完成后会向WebView对象发送事件,WebView类的EventStub对象处理该事件,并且完成后续初始化工作。4. 获取WebIconDatabase对象实例。5

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论