在Gadget開發人員看來——我當然是指你我這樣的IT民工,來開發一個Gadget的人,而不是Google大樓里成天琢磨怎么和微軟對著干的那幫子人——一個Gadget由三大部分組成:描述UI的一系列.xml文件;存放程序邏輯的.js文件以及資源。
下面是一個Gadget項目在Google Desktop Disigner里面的結構截圖。

資源這東西好理解,無非是程序要用到的各種圖片啦,字符串啦等等。讀者:字符串?什么意思?答:把程序會用到的一系列字符串統一存放,想引用的時候使用一個常量名字就可以,而不必在需要這些字符串的地方每次都重寫一遍,和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。下面一節就用一個小例子來看看具體如何做。別嫌我說得太詳細哦。