2008年10月15日星期三

认识了解Gears

前一段时间对Google Chrome有过简单的认识与了解,在体验新鲜出炉的Google Chrome浏览器中提到Google的Google Chrome Comic,其中提出通过Gears来扩展Web应用,但究竟什么是Gears以及其如何来扩展浏览器等,一直令人好奇。通过了解Gears应该可以了解Google将来究竟主推怎样的方式来扩展Web应用,当然包括Chrome浏览器及Android等,因为个人一直认为Gecko内核对扩展的支持非常方便、灵活、实用(具体可参考与Gecko相关的文档),但对基于WebKit内核的扩展相对来说不是那么的方便与直接,为了满足探究感,让我们开始了解Gears之旅吧。

一、什么是Gears?
Gears is an open source project that enables more powerful web applications, by adding new features to web browsers.

目前主要提供一组JS API以供Web应用使用,对应Web开发者来说其类似于prototype、dojo、jquery等JS库,但其实现是通过扩展浏览器来实现(不仅仅包含js代码还包含二进制代码等)。

主要的API模块有:
  • A Database module (powered by SQLite) that can store data locally.
  • A WorkerPool module that provides parallel execution of JavaScript code.
  • A LocalServer module that caches and serves application resources (HTML, JavaScript, images, etc).
  • A Desktop module that lets web applications interact more naturally with the desktop.
  • A Geolocation module that lets web applications detect the geographical location of their users.

通过Google Gears可以了解Gears的发展及目前开发状态等,其中有些已实现或打算实现的API还是非常有意思的如Geolocation、Audio、Camera等,一旦这些API能完善好的话确实非常有利于Web应用的扩展,比如说录音、摄像等。

如果对扩展Web应用如开发RIA等有兴趣的话,可以好好考虑哪些应用或业务,可以或需要扩展到Web上来,通过了解Gears,说不定Gears能给您很大的启发。。。。

二、如何利用Gears?
利用Gears,首先需要用户安装Gears如对Firefox来讲就是一个extension,对Chrome、Safari来讲是一个符合NPAPI的插件,对IE来讲就是一个ActiveX;其次利用Gears API开发相关应用页面,以供最终用户使用。

也许对最终用户来讲稍嫌麻烦,需要额外安装程序,但如果Gears能象Flash一样实用、好用,那时就不再会觉得很麻烦啦。

对开发者来讲利用Gears相对就简单啦。在页面包含
<script src="gears_init.js"></script>
<script>
if (!window.google || !google.gears) {
location.href = "http://gears.google.com/?action=install&message=<your welcome message>" + "&return=<your website url>";
}
</script>
然后就可以使用其中的API啦。

具体可参考Gears Resources and Tools中的gears_init.js、samples及其他API等文档。


三、初步探究Gears基本实现原理
通过初步了解Get gears_init.js可以基本了解Gears提供对IE、Firefox、Chrome、Safari等支持,但其实现方式各有不同。

1、对各浏览器的支持
对Firefox来讲,Gears扩展了一个GearsFactory JS对象,可供JS脚本直接调用,从JS的角度看相对于给window对象新增了一个对象,就像原先的document、navigator对象一样使用,只不过其功能不同而已。

对IE来讲,Gears扩展了一个Gears.Factory ActiveX对象,可通过JS脚本new ActiveXObject('Gears.Factory');来直接调用,从JS的角度看可以象使用XMLHttpRequest对象一样使用Gears.Factory。

对Chrome、Safari来讲,就有点特殊啦,也有点诡异的感觉。需要在当前文档动态添加一个MIMEType为application/x-googlegears的Object插件对象,而这个Object对象就是对应的google.gears.factory对象。

从这里就可以看出WebKit对扩展JS的支持,从架构设计不是那么的直接,需要由NPAPI插件机制来中转实现;而Firefox、IE都从架构上提供了相应扩展机制来扩展,相当的直接明了及与浏览器本身的统一。

2、google.gears.factory对Firefox支持的实现
浅谈Gecko关键部分之六认识javascript实现及应用中我们可以了解到Gecko中XPCOM组件通过xpconnect及对DOMCLASSINFO的定义,就可轻松的将XPCOM组件Binding给JS使用,就像Gecko中对Components、Components.Interfaces、xmlhttprequest等的实现。

在Gears中就是使用了类似的方式来Binding一个GearsFactory组件给JS环境使用。其中实现了一个实现了GearsFactoryInterface接口的名称为GearsFactory,ContractId 为"@google.com/gears/factory;1"的组件,具体代码详见gears\factory\Factory_ff.cc,然后在gears\base\firefox\Module.cc中注册该组件时使用
catMgr->AddCategoryEntry(JAVASCRIPT_DOM_CLASS,
kGearsFactoryClassName,
kDomciExtensionContractId,
PR_TRUE, PR_TRUE, NULL);
将该组件声明为需要由xpconnect Binding给JS使用。一旦启用xpconnect,xpconnect就会作相应处理,具体可参考nsDOMClassInfo::RegisterExternalClasses()等方法。这样就完成JS GearsFactory对象的实现。

3、google.gears.factory对Safari支持的实现
浅谈WebKit之JavaScriptCore/V8篇中我们可以知道WebKit中将DOM实现Binding给Javascript实现往往通过generate-bindings.pl生成的代码来静态Binding,这种方式无法满足动态Binding的需求。但是从浅谈Gecko关键部分之九Plugin中我们了解到NPAPI插件接口提供了一组接口可以将插件的接口动态Binding给JS环境,同时可以让插件与JS之间相互调用。

而WebKit中实现了对NPAPI插件接口的支持,这样Gears中实现了一个mimetype为application/x-googlegears的插件,将该插件对象当作google.gears.factory JS对象来提供给页面使用。

具体可参考gears\base\npapi\Module.cc、Npp_bindings.cc,其中的NPP_New()方法应该是主要入口,同时设置该插件为windowless。至于如何将插件的方法动态Binding给JS使用,可具体参考Webkit中对NPN_CreateObject、NPClass的实现支持等。

4、google.gears.factory对IE支持的实现
按照创建ActiveX及BHO等接口方法来实现Gears.Factory ActiveX,进而将该对象赋值给google.gears.factory。具体关于ActiveX及BHO相关的知识参考Microsoft文档。

5、对其他API接口的实现
虽然google.gears.factory实现了create、getBuildInfo、version等接口,但对通过create创建出来的提供给开发人员用的localserver、geolocation、httprequest、audio等对象是如何实现的呢?

体现Gears强大及方便的地方就在这里。Gears提供了一组统一的类及接口实现可以方便将自定义的类及接口Binding给对应浏览器的JS实现。针对Firefox,它通过扩展SpiderMonkey的方式直接扩展JS实现;针对Safari,它还是使用NPAPI、NPObject的方式来扩展。

具体可以参考一下gears\base\common\Js_runner_np.cc、Js_runner_ff.cc、Js_runner_ie.cc等;

这一组统一扩展JS实现的类及接口有:ModuleImplBaseClass、ModuleWrapperBaseClass、DispatcherInterface、Dispatcher、MarshaledModule、ModuleEnvironment等,其作用就是按照统一的方式方便的将自定义的类及接口Binding给不同的浏览器实现。

如果对这方面有兴趣,可以对这些类及接口之间的关系及实现进一步研究,看Gears究竟是如何将C/C++类实现Binding给JS。其实这一点对JS来讲非常有意义,因为一旦可轻松方便的扩展JS,那么JS的应用就会进一步的扩大,就象python一样,python脚本可以方便扩充其模块,C/C++类库也可方便的扩充成python模块,从而让python几乎无所不能。


四、如何扩展Gears API?
在初步了解Gears实现原理之后,正与Gears CreatingNewModules所描述,我们也可以利用Gears来扩展自己的API,在了解其他API的实现基础上,其实扩展一个自己的Gears API难度似乎并不太大。。。

期望大家有时间可以加入到Google Gears中来一起拓展Web应用。。。

五、总结
通过对Gears的初步了解,觉得Gears对浏览器的扩展主要体现在对JS方面的扩展,相当于JS功能库的扩充,并且主要体现在非UI方面,虽然其中有部分UI方面的内容,但相当少;而Adobe推出的flash、Microsoft推出的Silverlight主要是按照插件的方式基于html标准的embed/object进行扩充,往往涉及到UI方面,并都有自身的特色如内嵌脚本语言、播放video/audio、网络处理等等;而Gecko所拥有的extension确可以是全方位的(包括UI、xpcom、插件等等)。

目前随着Ajax及RIA的推广,各式各样的JS库如prototype、dojo、jquery等也层出不穷,但是针对JS功能库方面的扩展还没有一个相对通用的国际标准,也许Gears正好抓住这样一个发展的趋势才采取这种通过扩展JS接口,为开发人员提供API的方式来扩展Web应用。

Gears API一方面迎合了RIA等方面的需求,另一方面也推动浏览器的扩展。但是它似乎抛弃了UI方面的扩展如使用Gecko的XUL、Microsoft XAML等的可能,也许flash对UI方面有太多的优势,同时html5中的video/audio逐步提上日程,做一个类似于Silverlight的插件意义不大,还不如在JS方面下足功夫,同时全面拥抱html(如gmail、gmap、gdoc等),也许这就是Google目前对扩展Web应用的一点看法吧。。。


六、参考资源
Gears Project
Wiki Gears(software)

没有评论: