在Gadget开发人员看来——我当然是指你我这样的IT民工,来开发一个Gadget的人,而不是Google大楼里成天琢磨怎么和微软对着干的那帮子人——一个Gadget由三大部分组成:描述UI的一系列.xml文件;存放程序逻辑的.js文件以及资源。

下面是一个Gadget项目在Google Desktop Disigner里面的结构截图。

clip_image001

资源这东西好理解,无非是程序要用到的各种图片啦,字符串啦等等。读者:字符串?什么意思?答:把程序会用到的一系列字符串统一存放,想引用的时候使用一个常量名字就可以,而不必在需要这些字符串的地方每次都重写一遍,和Java中的property文件作用类似。

其余的两部分会分节来详细讲解。

当然说只有三部分,是指我们大多只关心这么多,实际上还有第四部分,一个Gadget Settings文件,其中大多是关于这个Gadget的元信息,什么作者啊,创建日期啊,uuid啊,户口所在地啊,最高学历啊,婚姻状况啊,哦,我给说成简历了(笑)。

前面也说到过,一个Gadget其实就是一个桌面应用程序(再一次的,不管写起来某些语法多么得像HTML,Gadget与Web都没有天然的联系),只不过这个程序在Gadget Host的管理之下,行话叫“托管”。Windows下没有单独的Gadget Host,它被合并在Google Desktop里面(算是另一种捆绑吧)。而Linux下的确有干干净净的Gadget Host,且有源码下载,我们所有对Gadget的理解也都源于这个版本和相关的文档。

那么在Gadget Host看来,一个Gadget是什么东西呢?

以我写的一个小Picasa Gadget为例,在Picasa Gadget初次加载之前,它是一个.gg的压缩包(其实就是一个标准的zip包,被改了后缀名而已),Gadget Host会从中读取需要的文件,然后做相应的解释。

Gadget Host可以看成只有两部分组成:一个UI的渲染器和一个JavaScript引擎。

说UI渲染器之前就不得不回头重提刚才说到的一个Gadget包括了一系列.xml文件这件事。实际上这些.xml文件就是用来指定你想写的Gadget的界面的,就是说,你的Gadget跑起来以后长成什么样子,是由这些个.xml文件来决定的(当然,严格说来可以使用JavaScript在运行时改变一些内容,但请不要抬杠,笑)。

这些.xml文件中最主要的是main.xml这个文件,你的Gadget窗口有多大,在什么位置有几个按钮,列表有没有滚动条,背景是什么颜色等等,都在这里指定。还包括这些东西上的事件监听函数也一并在这里声明(不知为何,让我莫名的想起微软的MFC,当然,严格说来可以使用JavaScript在运行时动态改变这些内容,但请不要再次抬杠,笑)。

UI渲染器干什么呢?就是来把这个.xml所要求的界面转换成具体的系统调用,让操作系统来完成绘图(好吧好吧,你喜欢严格,那我告诉你,Linux版本下首先被转换为Qt的C++类,由Qt来发起对系统绘图的调用)。

既然Gadget的程序逻辑都使用JavaScript来编写,理所应当的,Gadget Host必然要包含一个JavaScript解释器来解释这些代码,这个解释器也被叫做JavaScript引擎。Gadget Host里确实有这么个东西,叫做Spider Monkey,它恰好也是FireFox所使用的JavaScript引擎。广义上说,一个引擎的作用主要是解释它遇到的一切JavaScript代码,如果代码使用到核心JavaScript的功能和对象,它便直接提供;如果代码使用到了一些依赖于底层的对象(例如Gadget Host就提供了很多专有的JavaScript对象和方法供使用,这些都是核心JavaScript之外的东西),则引擎还要负责转发这样的请求(你可以说,这实际上是适配器做的事,我这样简化有助于理解,请不要一再抬杠,笑)。

也可以这样从逻辑上看Gadget的组成:即一个Gadget就是一组图形界面,加这些界面上每个控件(按钮啊,列表啊,输入框等等)的事件监听函数,这种界面描述与事件逻辑分离的程序模型,和微软的XAML+C#简直如出一辙。因此一个Gadget的开发实际上也就可以分为这两大步骤:先写界面的XML文件,再写逻辑部分的JavaScript。下面一节就用一个小例子来看看具体如何做。别嫌我说得太详细哦。