Phonegap為跨設備的應用開發提供了一個解決方案。如果某個應用只有js和html,則可以通過Phonegap的在線build工具,編譯出多個平台的app安裝包。當然通過Phonegap提供的js可以訪問部分設備的資源,如網絡連接(Connection)、相機(Camera)、文件(File)、存儲(Storage)等,具體可以參看Phonegap開發文檔。但很多Android應用,僅僅使用這些資源是滿足不了需求的,所以必然需要訪問本地接口的方法。
初步實驗,至少有兩個方法可以訪問本地的接口。
- 開發Phonegap Plugin。通過實現Phonegap提供的接口,然后在config.xml中注冊插件,就可以通過js開訪問了。具體可以參考Plugin Development Guide和Developing a Plugin on Android。
- 直接寫Java類,通過DroidGap.appView.addJavascriptInterface暴露Java接口。按照這篇博客可以寫出來。
對於第一種方法,雖然官方已經提供了教程,但我認為還是有必要梳理一下流程,因為官網的教程忽略了由於升級需要的更改。
- 實現CordovaPlugin 提供接口
- <span style="font-size: 14px;">package org.apache.cordova.plugin;
- import org.apache.cordova.api.CordovaPlugin;
- import org.apache.cordova.api.PluginResult;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- /**
- * This class echoes a string called from JavaScript.
- */
- public class Echo extends CordovaPlugin {
- @Override
- public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
- if (action.equals("echo")) {
- String message = args.getString(0);
- this.echo(message, callbackContext);
- return true;
- }
- return false;
- }
- private void echo(String message, CallbackContext callbackContext) {
- if (message != null && message.length() > 0) {
- callbackContext.success(message);
- } else {
- callbackContext.error("Expected one non-empty string argument.");
- }
- }
- }</span>
- 修改config.xml
添加以下代碼
- <span style="font-size: 14px;"><plugin name="Echo" value="org.apache.cordova.plugin.Echo" /></span>
- 為windows(或者其他對象)添加echo方法
官網為cordova.exec(...),這里需要根據2.6的js接口使用作以下修改。
- <span style="font-size: 14px;">window.echo = function(str, callback) {</span>
- <span style="font-size: 14px;"> <strong>var exec = cordova.require('cordova/exec');</strong>
- <strong>exec</strong>(callback, function(err) {
- callback('Nothing to echo.');
- }, "Echo", "echo", [str]);
- };</span>
- 通過js調用接口
- <span style="font-size: 14px;">window.echo("echome", function(echoValue) {
- alert(echoValue == "echome"); // should alert true.
- });</span>
另外,對於回調函數調用的線程有三種情況:
- 如果直接調用,即callbackContext.success(),則在WebCore 線程中執行,而是在UI線程。
- 如果希望在UI線程中直接,需要將回調函數封裝在Runanble中,放在cordova.getActivity().runOnUiThread中執行。
- <span style="font-size: 14px;">cordova.getActivity().runOnUiThread(new Runnable() {
- public void run() {
- ...
- callbackContext.success(); // Thread-safe.
- }
- });
- </span>
- 如果期望在單獨的線程中執行(不至於阻塞WebCore線程),則使用 cordova.getThreadPool().execute方法。
- <span style="font-size: 14px;"> cordova.getThreadPool().execute(new Runnable() {
- public void run() {
- ...
- callbackContext.success(); // Thread-safe.
- }
- });</span>

