嵌入式浏览器Konqueror的技术分析(1)


Konqueror是一个嵌入式浏览器,主要运行在Linux 和 BSD家族的操作系统上,我曾用过一段时间,来随我看看。

1  Konqueror/embedded概述

目前,嵌入式浏览器已经逐渐成为高端手机和PDA的标准配置。已经面市的大多数嵌入式浏览器是商业版本的,像opera和MS explorer等,而Konqueror/embedded是符合GNU条款的自由软件。Konqueror/embedded是针对嵌入式Linux,由著名的桌面操作环境KDE下的浏览器Konqueror派生出来的。Konqueror/embedded将Konqueror中关于KHTML、SSL、Javascript等内容继承了下来,同时简化了Konqueror中很多类的定义,剔除了依赖于KDElib部分,以适应在不同的嵌入式平台上移植和运行。两者都是基于Qt的,因此Konqueror/embedded也可以运行在Qt/X11环境下。Konqueror/embedded完整地支持HTML4和css1(部分支持css2)、JavaScript (ECMAScript 262)、cookies、SSL、IPv6;支持和管理兼容XBEL的书签,并且能够很好地支持中文网页浏览;可以将Konqueror/embedded作为一个flashplayer、pppdialer或文件管理器使用。2Konqueror/embedded的构成

图1Konqueror/embedded层次结构Konqueror/embedded是由底层网路连接、图形化用户界面和处理HTML绘制的引擎——KHTML构成的。

2  I/OSlaves

I/OSlaves 实现流程底层的通信协议实现是基于KIO/Slave机制来实现的;GUI界面采用了Kparts组件技术和Qt中的基本构件;而作为Konqueror/embedded的核心——KHTML,则运用了文档对象模型(DOM)所提供的API接口,并在DOM树上挂接javascript引擎、CSS解析器以及渲染引擎。

3  Konqueror/embedded中的关键技术

3.1底层通信协议的实现——I/OSlave机制

在KDE中采用I/OSlaves系统来访问各种数据。Konqueror/embedded沿用这种方式,通过I/OSlaves和进程间管道通信机制实现完整的浏览器功能。在基于Qt/X11的Konqueror中,同样采用I/OSlaves机制。简单说来,I/OSlaves就是那些从网络上获取文件或目录的进程,它们依赖桌面通信协议DCOP(Desktop Communications Protocol)与其他进程进行通信;但是,DCOP的实现又依赖于X11 ICE(Inter Client Exchange)库。在嵌入式平台上移植体积庞大的X11 lib是不现实的。Konqueror/embedded采用了另外一种进程间的通信机制:通过管道(pipe)实现主进程和其他I/OSlaves子进程之间的通信。

在KDE1.X之后,KDE的文件管理器和Konqueror等应用程序具有网络透明的特征,Konqueror/embedded也继承了这个特性。Konqueror/embedded不管对本地文件还是远程文件都采用URL(统一资源定位符)进行标识。网络透明性允许应用程序的用户使用与处理本地文件相同的方法来处理远程文件。在KDE的文件选择器能够通过诸如 FTP、SMB甚至 Webdav(在 KDE3中)等方式列出远程目录。网络透明性和I/OSlaves机制是靠KIO类来实现的。KIO类提供了几乎所有的文件管理功能。其中,KIO∷NetAccess提供文件下载、上传以及临时文件的创建或删除等简单的同步访问功能。这是一种阻塞调用方式。如果用Konqueror/embedded下载网络上的数据,在数据没有完全加载之前,当前进程将会被阻塞。数据流完全加载之后,网页才可以再次渲染或刷新。KIO∷Job提供较为复杂的异步功能,包括打开、创建、复制、删除以及重命名等与文件或目录相关的操作。Konqueror/embedded正是依靠KIO∷Job来实现网页访问这样的异步工作的。一旦某个job被启动之后,它将运行在后台,并且不会阻塞父进程。Konqueror/embedded中各种协议,如HTTP、FTP等是由一些独立的进程来实现的。这些独立的进程被称为Slaves。Slave是KIO∷lavebase的子类,KIO∷Slavebase中定义了一些虚函数,不同的Slave必须重载这些接口。Slave以函数库的形式存在于系统中,提供给相应的job调用。Slaveinterface运行在应用端(job),Slavebase运行在Slave端。一般情况下,创建的job会处在队列中,当事件循环处理到该job时,KIO为队列中的job分配适当的Slave。Slave的管理和调度是由调度器scheduler来执行的,scheduler将job队列加入适当的协议(Slave)中。当该job结束之后,Slave进程不会立即停止,会在空闲区域中等待一定的时间。这种机制的优点在于,如果有几个job访问的是同一个主机,那么就不需要重新启动新的进程,并且不需要再次进行协议握手。在同一时间,面向同一种网络协议,系统中最多只能启动3个Slave进程。如果引用该协议的job超过这个数目,那么多余的job将被添加到队列中,直到又有空闲的Slave进程可用。图2描述了Konqueror/embedded中关于底层协议(Slave)和任务(job)的实现过程。

3.2GUI系统的实现——Kparts

组件技术(1) Konqueror/embedded中的组件

虽然,Konqueror/embedded的UI界面是直接继承QMainWindow的,但是,UI界面的功能和布局是由组件来实现的,QMainWindow只是这些组件的宿主。在Konqueror/embedded启动初始化过程中,首先加载一个特殊的组件——KHTMLPART。KHTMLPART负责其他组件(如Kflashpart、Kplaintextpart等)的加载和管理。采用Kparts组件编程技术能够使得Konqueror/embedded的功能得到扩展,而不需要重新修改底层代码,同时增强了Konqueror/embedded的可定制性。 Konqueror/embedded将Web 浏览器、flsahpalyer、文本编辑器和简单音频播放器都作为Kparts组件嵌入到主窗口中。Kparts组件编程技术能够通过将图形组件嵌入应用程序的窗口使需要同一功能的应用程序共享一个组件。Kparts组件分只读组件和读写组件。只读组件ReadOnlyPart 类为实现任何类型的查看器提供了一个公共框架。如果提供了一个文件的 URL,那么所有这些查看器都可以显示该文件,并阻止对该文件的任何修改。在Konqueror/embedded中,像Web 浏览器、flashpalyer、简单音频播放器都属于只读组件。另外一种读写组件ReadWritePart 类是 ReadOnlyPart 的扩展,它添加了修改和保存文档的可能性,像Konqueror/embedded中嵌入的文本编辑器,属于读写组件。

(2) Konqueror/embedded中组件实现技术

以Konqueror/embedded中文本编辑器组件(Kplaintextpart)为例,组件必须要由三个元素组成,包括窗口构件、组件功能和用户界面。窗口构件必须是 QWidget 的子代,Konqueror/embedded中的文本编辑器继承于QmultiLineEdit类;除了窗口构件外,还需要组件提供的功能,Konqueror/embedded的中文本编辑器提供前进、后退、剪切、复制和全选等附加功能;当然还要提供访问那些功能的用户界面(操作以及 XML文件)。Konqueror/embedded中的文本编辑器只提供了窗口构件功能的菜单项。在XML格式文件Kplaintextpart.rc中定义其用户界面的布局,它和应用程序代码是分开的。当该文本编辑器被嵌入到Konqueror/embedded时,采用称为XMLGUI的技术将组件菜单和原来的用户界面合并。

Konqueror/embedded中的文本编辑器组件构成如图3所示。

图3文本编辑器组件结构Kparts组件的最大特征在于它的可重用性。要做到这一点,就必须将组件编译到共享库中。希望动态地打开共享库的应用程序使用 KLibLoader 类。KLibLoader 处理库的定位、打开以及调用初始化函数。初始化函数是库的入口点。这个初始化函数创建一个工厂,由组件的工厂来创建组件。具体的实现方法如图4所示。

3.3KHTML绘制引擎的实现

KHTML引擎作为 Konqueror/embedded的核心,包含了dom、xml、html、css、rendering、misc、ecma七个子目录。这几个子目录的功能分别如图5所示。

从这个功能结构图可以看出,Konqueror/embedded的KHTML引擎是基于XML的DOM技术来构建的,与现在的大部分浏览器的架构是相似的。DOM是以层次结构组织的节点或信息片断的集合。在这种层次结构中可以利用导航仪搜寻特定的信息。同时,DOM还提供了一套API,可以用JAVA,C++或C来实现这些API。

现在最常用的解析XML文件的方法有四种:文档对象模型(DOM,Document Object Model)、用于XML的简单API(SAX,Simple API for XML)、JDOM和用于XML解析的Java API(JAXP,Java API for XML Parsing)。它们有各自的优点和弱点,因而适用在不同的场合。Konqueror/embedded中采用的是DOM技术。它所提供的接口和方法可以对构建的DOM树的节点进行添加、删除,甚至可以删除树的几个部分,还可以重新排列树和添加新的分支;但是,由于DOM构建整个文档驻留内存的树,如果文档很大,就会要求有极大的内存,这对于一般内存不大的嵌入式设备是个挑战。另外,DOM构建整个文档的每个节点和元素,如果用户关心的只是其中的一部分,那么

图4组件创建步骤图5Konqueror/embedded的构成将会引起资源的浪费;同时,DOM是在用户获取控制权之前加载整个文档的,如果文档很大,将产生明显的延迟。Konqueror/embedded中,采用DOM技术来解析HTML/XML的最大优点在于,DOM会自动地保存已经解析过的文档,而不必要在用户希望浏览历史的时候再重新解析文档。

Konqueror/embedded中采用的是DOM2级规范,分为DOM2 Core和DOM2 HTML。相对于DOM Level1,DOM2增加了对XML文档处理的一些接口和方法:

视图(view),提供视图与文档的联系;

样式表(style sheet),提供访问和修改样式表的方法;

层叠样式表(CSS2),提供CSS2兼容的方法;

事件(events),提供各种事件的接口;

文档遍历(document traversal),提供遍历文档层次的接口;

文档范围(document range),提供分割文档范围的接口。


相关内容