【phonegap】使用的java與js互相調用的原理

http://blog.sina.com.cn/s/blog_6e4d9a9b0101ny26.html

Phonegap使用的java與js互相調用的原理。phonegap實現的模型剛也說了,有同步和異步兩種。js實現的api,所以是js先會調用java代碼,然後再返回給js。對於同步的而言,就是js調用java,然後java返回一個結果作爲返回值。對於異步的而言,可能js掉了很多java代碼,但是立即返回,然後java代碼執行結束後再回調js代碼,這裏就涉及到js調java,然後java再調用js。

對於js調用java:

js調用java的入口是通過在js中調用prompt方法,這很奇怪吧,這個方法本來是讓瀏覽器彈出個輸入框的。我當初找了好久也沒發現phonegap到底怎麼搞得的讓js調用java的代碼,後來看到一會覺得該是這個方法,但是這是一個瀏覽器的客戶端自己的東西,而且怪異的是瀏覽器並沒有彈出輸入框,後來終於發現。

在DroidGap.java中有個hack,重載了WebviewClient的onJsPrompt方法,然後執行了自己的邏輯。也就是js調用prompt的時候,java端瀏覽器代碼接受到這個,然後在響應的處理函數中根據傳過來的參數,實現了一些特別的邏輯。可以從這個方法的註釋上看出一二。

private LinkedList javascript;

服務器保存要回調的js的代碼,供js客戶端取回,這裏java端是服務器端,js端是客戶端,服務器端不可能請求客戶端做啥,是b/s模型,所以phonegap實現了兩種服務模型,一種是輪詢,一種是XHR異步回調,也就是Ajax的模型。src/com/phonegap/CallbackServer.java是回調服務器的代碼所在處。從類的註釋中可以看到。

This class provides a way for Java to run JavaScript in the web page that has loaded PhoneGap.
The CallbackServer class implements an XHR server and a polling server with a list of JavaScript statements
that are to be executed on the web page.
 

CallbackServer提供的這兩種模型,一種是XHR,一種是輪詢,輪詢很簡單了,callbackserver服務器端,有一個保存回調js的列表,前面所說,然後每隔一段時間客戶端的js會詢問一次服務器,是否有需要回調的js,如果有則調用,然後每隔一段時再查詢一次服務器。而基於XHR的,其實這個就是ajax用的機制了,js發起一個異步請求,然後服務器會在返回數據之前保持住這個連接,當返回數據就位後,服務器給請求客戶端返回數據,然後關閉連接。然後客戶端接受並且處理。

剛說了服務器端的代碼實現,現在來看一下客戶端js的相關代碼。

PhoneGap.JSCallback = function() {
...
xmlhttp.open("GET", "http://127.0.0.1:"+PhoneGap.JSCallbackPort+"/"+PhoneGap.JSCallbackToken , true);
xmlhttp.send();
}

這個是XHR模型的代碼,客戶端js使用xhr請求服務器來獲取js代碼,進行回調。

PhoneGap.JSCallbackPolling = function() {
...
    var msg = prompt("", "gap_poll:");
    if (msg) {
        setTimeout(function() {
            try {
                var t = eval_r(""+msg);
            }
            catch (e) {
                console.log("JSCallbackPolling: Message from Server: " + msg);
                console.log("JSCallbackPolling Error: "+e);
            }
        }, 1);
        setTimeout(PhoneGap.JSCallbackPolling, 1);
    }
    else {
        setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod);
    }
}

這個是輪詢方式的,可以看到客戶端每隔PhoneGap.JSCallbackPollingPeriod段時間,就請求一次服務器(通過prompt("","gap_poll:");)。

******************************************************************************************************************

iOS:

通過讓本地代碼攔截JavaScript中調用的 window.location=”gap://Class.method/args”命令,來實現從JavaScript到本地代碼之間的通信。在本地 代碼攔截該命令後,解析獲取的參數,然後調用對應的類、方法並傳遞參數。對應的,使用 UIWebView.stringByEvaluatingJavaScriptFromString來實現本地代碼調用JavaScript。


Android:

通 過攔截JavaScript的prompt命令實現從JavaScript到本地代碼的通信。JavaScript prompt命令默認會彈出對話框,而PhoneGap的Android本地代碼會攔截該對話框,並進一步取得JavaScript數據。相應 的,Android上的PhoneGap內部,使用Java實現了一個HTTP服務器,通過持久性的XHR連接,JavaScript可以不斷輪詢內部 XHR服務器存儲的信息,從而實現了從Java到JavaScript方向的通信。


BlackBerry 4.x:

JavaScript 與本地代碼之間的唯一通信方式是通過document.cookie實現的。JavaScript設定Cookie,本地代碼從Cookie中獲取信息。 對應的,本地代碼也可以設定Cookie,允許JavaScript從Cookie中獲取本地代碼信息。


BlackBerry WebWorks:

新 的BlackBerry WebWorks SDK更好地支持了Java與JavaScript之間的交互通信。通過ScriptEngine.addExtension,Java對象可以被暴露給 JavaScript,而對應的Java可以使用ScriptEngine.executeScript來調用JavaScript。


Windows Phone 7:

在Windows Phone 7中,JavaScript通過window.external.Notify可以將信息發送給本地代碼。而相應的,WebBrowser.InvokeScript允許本地代碼調用JavaScript。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章