Phonegap通过JS访问本地接口的两种方法

时间:2021-05-08 02:41:29

Phonegap为跨设备的应用开发提供了一个解决方案。如果某个应用只有js和html,则可以通过Phonegap的在线build工具,编译出多个平台的app安装包。当然通过Phonegap提供的js可以访问部分设备的资源,如网络连接(Connection)、相机(Camera)、文件(File)、存储(Storage)等,具体可以参看Phonegap开发文档。但很多Android应用,仅仅使用这些资源是满足不了需求的,所以必然需要访问本地接口的方法。

初步实验,至少有两个方法可以访问本地的接口。

  • 开发Phonegap Plugin。通过实现Phonegap提供的接口,然后在config.xml中注册插件,就可以通过js开访问了。具体可以参考Plugin Development GuideDeveloping a Plugin on Android
  • 直接写Java类,通过DroidGap.appView.addJavascriptInterface暴露Java接口。按照这篇博客可以写出来。

对于第一种方法,虽然官方已经提供了教程,但我认为还是有必要梳理一下流程,因为官网的教程忽略了由于升级需要的更改。

  • 实现CordovaPlugin 提供接口
  1. <span style="font-size: 14px;">package org.apache.cordova.plugin;
  2. import org.apache.cordova.api.CordovaPlugin;
  3. import org.apache.cordova.api.PluginResult;
  4. import org.json.JSONArray;
  5. import org.json.JSONException;
  6. import org.json.JSONObject;
  7. /**
  8. * This class echoes a string called from JavaScript.
  9. */
  10. public class Echo extends CordovaPlugin {
  11. @Override
  12. public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
  13. if (action.equals("echo")) {
  14. String message = args.getString(0);
  15. this.echo(message, callbackContext);
  16. return true;
  17. }
  18. return false;
  19. }
  20. private void echo(String message, CallbackContext callbackContext) {
  21. if (message != null && message.length() > 0) {
  22. callbackContext.success(message);
  23. } else {
  24. callbackContext.error("Expected one non-empty string argument.");
  25. }
  26. }
  27. }</span>
  • 修改config.xml

添加以下代码

  1. <span style="font-size: 14px;"><plugin name="Echo" value="org.apache.cordova.plugin.Echo" /></span>
  • 为windows(或者其他对象)添加echo方法

官网为cordova.exec(...),这里需要根据2.6的js接口使用作以下修改。

  1. <span style="font-size: 14px;">window.echo = function(str, callback) {</span>
  2. <span style="font-size: 14px;">    <strong>var exec = cordova.require('cordova/exec');</strong>
  3. <strong>exec</strong>(callback, function(err) {
  4. callback('Nothing to echo.');
  5. }, "Echo", "echo", [str]);
  6. };</span>
  • 通过js调用接口
  1. <span style="font-size: 14px;">window.echo("echome", function(echoValue) {
  2. alert(echoValue == "echome"); // should alert true.
  3. });</span>

另外,对于回调函数调用的线程有三种情况:

  • 如果直接调用,即callbackContext.success(),则在WebCore 线程中执行,而是在UI线程。
  • 如果希望在UI线程中直接,需要将回调函数封装在Runanble中,放在cordova.getActivity().runOnUiThread中执行。
  1. <span style="font-size: 14px;">cordova.getActivity().runOnUiThread(new Runnable() {
  2. public void run() {
  3. ...
  4. callbackContext.success(); // Thread-safe.
  5. }
  6. });
  7. </span>
  • 如果期望在单独的线程中执行(不至于阻塞WebCore线程),则使用 cordova.getThreadPool().execute方法。
      1. <span style="font-size: 14px;"> cordova.getThreadPool().execute(new Runnable() {
      2. public void run() {
      3. ...
      4. callbackContext.success(); // Thread-safe.
      5. }
      6. });</span>