androidphonegap
A. phonegap和android sdk之間怎麼連接
Java 端介紹
Java 端作為後台調用 Android 本地 SDK 的介面,主要實現了如下的功能:
建立通訊機制,提供介面給瀏覽器端,方便 JavaScript 進行調用。
數據隊列的維護,以保證瀏覽器端的調用後產生的數據可以回送。
插件體系的建立,提供整個框架的可擴展性。
而這三部分的功能對應到代碼中則是如下的幾個重要的 Java 類:
DroidGap、CallbackServer
CallbackServer
Plugin、PluginManager
因此我們需要依次來了解這幾個重要的 Java 類的具體實現,這樣才可以對 PhoneGap 在 Android 上的體系有一個很好的了解。
DroidGap 的實現
當 我們完成一個基本的 PhoneGap 的示例後,我們就會發現,在使用 PhoneGap 進行開發的手機應用中,第一步就是將繼承關系 extends Activity 修改為 extends DroidGap。因此,DroidGap 是整個應用開始的地點,首先需要了解 DroidGap 的內容。
在源碼中可以看到 DroidGap 繼承自 PhonegapActivity,而 PhonegapActivity 是一個抽象類,繼承自 Activity,但是具體的實現都是集中在 DroidGap 類中。
因 此,我們繼續回到 DroidGap 類中,當我們知道 DroidGap 類也是一個 Acitvity 後,就會明白,DroidGap 在 onCreate 方法中實現了整個類最初的一些操作,代碼的實現則集中在 onCreate() 和 init() 這兩個方法中,具體的流程如下:
設置 WebView
設 置 WebView 的代碼都集中在 init() 方法中,其中一個值得注意的工作是設置 WebChromClient。代碼中提供了一個繼承自 WebChromClient 的類,重寫了其中的 onJsAlert,onJsConfirm,onJsPrompt 等方法。而在 onJsPrompt() 方法中,實現了 PhoneGap 中 Java 端和瀏覽器端通訊的關鍵一步。因此,值得我們專門的關注其代碼,具體的功能實現代碼如下,我們已經過濾了一些錯誤處理、安全驗證等等可能會妨礙我們對重要 的功能實現理解的代碼:
代碼清單 1. WebView 代碼
if (reqOk && defaultValue != null && defaultValue.length() > 3
&& defaultValue.substring(0, 4).equals("gap:")) {
JSONArray array;
try {
array = new JSONArray(defaultValue.substring(4));
String service = array.getString(0);
String action = array.getString(1);
String callbackId = array.getString(2);
boolean async = array.getBoolean(3);
String r = pluginManager.exec(service, action, callbackId, message, async);
result.confirm(r);
} catch (JSONException e) {
e.printStackTrace();
}
}
// Polling for JavaScript messages
else if ......
在此,我們就可以明白,實現 JavaScript 與 Java 端通訊的原理是 JavaScript 利用 prompt 來傳遞調用信息的數據,在 onJsPrompt 中,重寫的方法截獲了這些數據,在完成了對數據格式等等分析後,按照要求進行具體的調用。而具體的調用利用是的 PluginManager 類,這將在隨後說明。
綁定 js
在 完成 WebView 的設置後,再將 PhoneGap 和 js 綁定,實現 js 與 PhoneGap 的通訊。在這一步中主要的內容就是實例化了 CallbackServer 和 PluginManager 兩個類。因此,更多的內容會在隨後對這兩個類的介紹中再說明。
載入 URL
LoadUrl 方法也是實現一個 PhoneGap 示例後很熟悉的方法,在 loadUrl 中,完成基本的字元串處理後,主要利用 runOnUiThread 開始處理,其中第一步檢測是否需要提供載入的顯示,之後使用 WebView 的 loadUrl 載入內容,並且設置超時時間。
至此,Java 端的准備工作也就完成,實現了 UI 的載入。可以看到,在 DroidGap 類中最重要的一個部分就是截獲 JavaScript 的 prompt 數據。這是實現瀏覽器端和 Java 端通訊的基礎。
Plugin 的實現
Plugin 是一個抽象類,實現了 IPlugin 介面,PhoneGap 中利用 Android SDK 實現邏輯代碼的途徑就是通過繼承 Plugin 來實現。應此 Plugin 本身非常簡單,最主要的部分是提供一個 execute 方法,如下:
public abstract PluginResult execute(String action, JSONArray args, String callbackId);
Plugin 的實現中的重要邏輯在其中來實現,它返回的是一個 PluginResult 對象,這個對象主要負責傳遞數據信息,包括的成員主要如下:
private final int status;
用於返回狀態,status 與一個 enum 類型相關,用於標注插件的執行結果如何。
private final String message;
用於返回數據信息。
PluginManager 的實現
PluginManager 事實上是 DroidGap 類和具體的繼承自 Plugin 的插件的聯系紐帶,由它來尋找和載入插件,並且調用。
首 先,PluginManager 在構造函數中,調用了 loadPlugins 方法,該方法負責解析 xml 配置文件,對應每個 plugin,調用一次 addService 用於注冊插件,具體的注冊地點,是通過維護一個 HashMap<String, String> 來實現,分別保存 serviceType, className。在成員中,有另外一個 HashMap<String, IPlugin> 用於實現 className 和 IPlugin 類的綁定。這樣就實現了 serviceType 和 IPlugin 的對應。
在 PluginManager 中,執行插件的方法 exec 是主要功能,我們將會詳細說明一下這個方法的過程:
利用查詢之前提到的 HashMap<String, String> 將 service 和 className 對應起來,這樣我們就獲得了提供功能的插件類的位置。
通過 getClassByName 來獲得插件類。
完成類型檢測,確定對應的類是一個插件類。
執行 addPlugin 方法,其中則將第 2 步中獲得插件類的 className 和具體的 Plugin 介面的實現綁定,具體的實現就是上文中提到的 HashMap<Strig,IPlugin>。
判斷 Plugin 是否需要非同步執行,再根據情況,選擇直接執行或者是建立新的線程來執行。
完成執行後,得到的數據會根據情況交給 CallbackServer 來處理,PluginManager 會調用 DroidGap 中的 sendJavaScript 來將數據交給 CallbackServer,事實上,DroidGap 中的 sendJavaScript 不過是對 CallbackServer 中的 sendJavaScript 包裝,實際調用的是 CallbackServer 中的 sendJavaScript 方法,這涉及到了 CallbackServer 類,隨後就會說明。
執行結果的轉換則是利用 PluginResult 中的一些 to***String 方法。這些方法返回了一個 String 類型,其中包括了具體的 JSON 對象和 callbackId,具體的形式則是一個 js 代碼,用於前端的調用。
CallbackServer 的實現
CallbackServer 實現了 Runnable 介面,具體的功能就是維護一個數據的隊列,並且建立一個伺服器,用於 XHR 的數據傳遞,對數據的隊列的維護利用的是 LinkedList<String>。
由於實現的是 Runnable 介面,在 CallbackServer 中,最主要的方法就是 run() 方法,run() 方法的具體內容簡介如下:
首先利用 ServerSocket 監聽埠,具體埠則自由分配。
在 accept 後則是對 HTTP 協議的解析,和對應的返回 status code。
在驗證正確後,利用 getJavascript 方法得到維護的 LinkedList<String>() 中的保存的 js 代碼,如果為空則返回 null。
這些具體的 string 類型的 js 代碼則利用 socket 作為 response 返回給前端。
之後就是對隊列維護的方法,這時理解之前的 sendJavaScript 則很簡單,該方法與 getJavaScript 相反,一個是從 LinkedList 中取出 js 代碼,一個則是加入。
綜 上,CallbackServer 實現的是兩個功能,一個是 XHR 的 SocketServer,一個是對隊列的維護。而完成 CallbackServer 類的說明後,Java 端的主要功能也都說明完畢。隨後會說明瀏覽器端的說明,在完成瀏覽器端說明後,我們就會明白整個 PhoneGap 框架運行的原理。