初談 Google Gears 的程式寫作


Google Gears 推出後,我還蠻喜歡他補強現今瀏覽器的功能,自己研究了一下,把心得記錄下來與同好分享。

Google Gears 是一個「跨瀏覽器、平台」的一個瀏覽器插件(Plug-in),也就是說它可以安裝在像 IE、Firefox 等知名的瀏覽器中,不過目前還不是支援得很完善,目前穩定版本(版本編號:0.3.14.2)僅支援下列平台及瀏覽器:

  • Windows
    • IE 6/7
    • Firefox 1.5+ ~ 2.0.x
  • Windows Mobile
    • Internet Explorer 4.01
  • Linux
    • Firefox 1.5+ ~ 2.0.x
  • Mac
    • Firefox 1.5+ ~ 2.0.x

不過 Google Gears 是一個 open source 的 project,如果你有興趣但使用的瀏覽器又不在上述列表之中,可以嚐試到它的專案網頁去把 source check out 回來自己作一個新版(e.g., for Firefox 3)的 Google Gears。而利用 Google Gears 寫程式的參考文件則可以到這裡來瀏覽。

簡介

Google Gears 目前可以分為三個部份:

  1. Google Gears Local Server Local Server

    這個部份讓你可以利用 Google Gears 在本地端(也就是自己的系統上)建立的一個小型的伺服器,來存放網頁上的一些靜態檔案,如:HTML、CSS、JS 或圖片檔案。這樣做的好處是你可以把網站上這些不常更動的靜態檔案,讓使用者存放在自己的機器上,這樣除了在讀取速度上會增加不少以外,即使它的機器沒有連上網路也可以存取這些頁面。

  2. Google Gears Database Database

    這個部份是許多人第一次聽到 Google Gears 所知道的,它就是在你的機器上建立了一個 SQL-based (應該就是用 sqlite 的引擎)的小小資料庫,讓你可以同步網站的一些資料到這個小型資料庫裡。當使用者離線時,依然可以透過這個小型的資料庫來存取內容。

  3. Google Gears WorkerPoolWorkerPool

    WorkerPool 是我覺得整個 Google Gears 裡最酷的地方,因為目前各個瀏覽器的 JavaScript 執行引擎都還是單一執行緒(Single-threaded)的,也就是你在網頁上寫的 JavaScript 程式碼並沒有多執行緒的概念,頂多就是利用 setInterval/setTimeout (還有 XMLHttpRequest)來做到部份的非同步的效果,套句 Google Taipei 工程師在 OSDC.tw 2008 上講的:「這樣你電腦的四核心就無法完全發揮了!」
    而 Google Gears 的 WorkerPool API 正式可以讓你利用系統原生的執行緒來撰寫「多執行緒的 JavaScript 程式」,如此便可以努力榨乾利用系統的效能來做一些費時費力的 JavaScript 程式。

程式碼撰寫

以下我將簡單地介紹一下,如何快速(?)上手 Google Gears 來開發程式。

  1. 初始化及引導使用者安裝 Google Gears:

    首先,你先引入 Google Gears 提供的 gears_init.js 來作一些基本的 Google Gears 初始化,然後,在你自己的 JavaScript 裡頭,加入這樣的程式碼:

    [code lang="javascript"]
    if (!window.google || !google.gears) {
    if (confirm('使用 OOO 功能必須安裝 Google Gears,請問您要安裝嗎?')) {
    location.href = 'http://gears.google.com/?action=install&message=<加入你的訊息>&return=<安裝後要導回的網址>';
    } else {
    alert('若不安裝 Google Gears 則將無法使用 OOO 功能!');
    }
    }
    [/code]
    簡單地說就是利用檢查有沒有定義 window.google.gears 來看使用者是否有安裝 Google Gears,如果沒有定義,則詢問他是否要安裝,如果確定則把它導向 Google Gears 的安裝畫面。

  2. 使用 Local Server

    Google Gears 的 Local Server API 中可以指定要擷取(capture) 哪些靜態檔案,而你也可以在 server 端擺一個 JSON 檔案來定義哪些檔案要同步,而這個 json 檔案也許會長這樣:
    [code lang="javascript"]
    {
    "betaManifestVersion": 1,
    "version": "v1",
    "entries": [
    {
    "url": "/offline.html",
    "src": "../offline.html"
    },
    {
    "url": "/js/offline.js",
    "src": "offline.js"
    },
    {
    "url": "/js/gears_init.js",
    "src": "gears_init.js"
    }
    ]
    }
    [/code]
    其中你需要修改的是 version 及 entries 的部份,Local Server API 中有一個 method 就是檢查這個 json 檔案中的 version 參數來決定要不要下載新的版本,而 entries 則是告訴 Local Server API 要抓哪些檔案。其中 url 的部份是相對於網站的路徑,而 src 則是相對於此 json 檔案的路徑

    接著,當你在網頁中放了一個按鈕,用來驅動 Google Gears Local Server 的同步時,可以參考下列程式碼:
    [code lang="javascript"]
    // 先建立 local server,這裡 create 的參數不用修改。
    try {
    var localServer = google.gears.factory.create('beta.localserver');
    } catch (ex) {
    alert(ex.message);
    return;
    }

    // 建立儲存空間,名稱則可以自己取
    var store = localServer.createManagedStore("foo-store");
    // 指定 json 的 url
    store.manifestUrl('放入上述 json 檔案的 url');
    // 開始確定版本及同步
    store.checkForUpdate();

    // 為了確認是否同步結束了,可以加入下列的 timer 來檢查:
    var timer = google.gears.factory.create('beta.timer');
    // 每 500ms 檢查一下
    var timerId = timer.setInterval(function() {
    // 同步完成
    if (store.currentVersion) {
    timer.clearInterval(timerId);
    alert('同步完成');
    }
    }, 500);
    [/code]

    這樣同步完成後,使用者的機器上就存了一份 json 檔案裡指定的 entries 了。

  3. 使用 Database

    使用 Database API 的部份與 Local Server API 很像,流程就如下列程式碼所述:
    [code lang="javascript"]
    // 先建立 database,這裡 create 的參數不用修改。
    try {
    var db = google.gears.factory.create('beta.database');
    } catch (ex) {
    alert(ex.message);
    return;
    }

    // 開啟資料庫名稱
    db.open('foo-db');
    db.execute('執行你想做的 SQL 指令吧');
    [/code]

    使用 Database API 就是那麼簡單 XD,剩下的就是看著參考文件來下 SQL 指令了。

    而從 Google Gears Database 裡取出資料也不難,直接使用:
    [code lang="javascript"]
    ... // 已建立、開啟好 db

    var rs = db.execute('select * from blah');
    while (rs.isValidRow()) {
    ... // 用 rs.field(number) 來取欄位資料
    rs.next(); // 繼續下一筆資料
    }
    [/code]

  4. 使用 WorkerPool

    如果你使用其它語言寫過多執行緒的程式,那 WorkerPool 的用法也很直覺,WorkerPool 的 worker 有兩程執行程式碼的方式:

    1. 將 WorkerPool 綁在 message 上,當收到 message 時才去做事。
    2. 直接產生一個 worker 來做指定的程式碼。

    這是第一種方式:
    [code lang="javascript"]
    try {
    var workerPool = google.gears.factory.create('beta.workerpool');
    } catch (ex) {
    alert(ex.message);
    return;
    }

    workerPool.onmessage = function(msgText, sender, msgObj) {
    ...... // 收到 message 時要做的事情
    };

    ....

    // 送出 message
    workerPool.sendMessage(........);
    [/code]

    或是另一種方式:
    [code lang="javascript"]

    var doFoo = function() {
    .... // 某個要做事的 function
    };

    // 建立 worker去執行帶入的程式碼
    var workerId = workerPool.createWorker("doFoo()");

    [/code]

    第二種方式比較值得注意的是 createWorker 的參數是字串,也就是要執行的程式碼,而不像一般處理 callback/handler 那樣直接帶入 function 的 object。

大概就為各位簡介至這裡,我也還在學習 Google Gears 的使用,有在寫網頁的人可以思考一下怎麼利用 Google Gears 的特性來為各位的網頁增加更多的可能 🙂