Android Java 和 Phonegap Javascript 之间的通信?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2727763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Communication between Android Java and Phonegap Javascript?
提问by zorglub76
I believe that it's possible to call Java methods from (PhoneGap) Javascript.
我相信可以从 (PhoneGap) Javascript 调用 Java 方法。
Anyone knows how to do that?? (I know how to do it by changing the source code of PhoneGap, but I'd avoid that)
有谁知道怎么做??(我知道如何通过更改 PhoneGap 的源代码来做到这一点,但我会避免这样做)
回答by zorglub76
I finally made it work.
我终于让它工作了。
Create a class with methods you want to use:
public class MyClass { private WebView mAppView; private DroidGap mGap; public MyClass(DroidGap gap, WebView view) { mAppView = view; mGap = gap; } public String getTelephoneNumber(){ TelephonyManager tm = (TelephonyManager) mGap.getSystemService(Context.TELEPHONY_SERVICE); String number = tm.getLine1Number(); return number; } }
In your main activity add a Javascript interface for this class:
public class Main extends DroidGap { private MyClass mc; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.init(); mc = new MyClass(this, appView); appView.addJavascriptInterface(mc, "MyCls"); super.loadUrl(getString(R.string.url)); } }
In Javascript call window.MyCls methods:
<script> $(function(){ $("#phone").text("My telephone number is: " + window.MyCls.getTelephoneNumber()); }); </script>
使用您要使用的方法创建一个类:
public class MyClass { private WebView mAppView; private DroidGap mGap; public MyClass(DroidGap gap, WebView view) { mAppView = view; mGap = gap; } public String getTelephoneNumber(){ TelephonyManager tm = (TelephonyManager) mGap.getSystemService(Context.TELEPHONY_SERVICE); String number = tm.getLine1Number(); return number; } }
在您的主要活动中,为此类添加一个 Javascript 接口:
public class Main extends DroidGap { private MyClass mc; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.init(); mc = new MyClass(this, appView); appView.addJavascriptInterface(mc, "MyCls"); super.loadUrl(getString(R.string.url)); } }
在 Javascript 中调用 window.MyCls 方法:
<script> $(function(){ $("#phone").text("My telephone number is: " + window.MyCls.getTelephoneNumber()); }); </script>
Note:
笔记:
As mentioned in the comment, for Android version 4.2 and above, add @JavascriptInterface
to the method which you want to access from your HTML page. Reference.
如评论中所述,对于 Android 4.2 及更高版本,添加@JavascriptInterface
到您要从 HTML 页面访问的方法。参考。
回答by Karfield
addJavaScriptInterface(mc, "MyCls")
without Gap init()
ed may cause crush of the app, you'd better add super.init()
before addJavascriptInterface()
addJavaScriptInterface(mc, "MyCls")
没有Gap init()
ed可能会导致app崩溃,你最好super.init()
在添加之前addJavascriptInterface()
public class Main extends DroidGap
{
private MyClass mc;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
mc = new MyClass(this, appView);
appView.addJavascriptInterface(mc, "MyCls");
super.loadUrl(getString(R.string.url));
}
}
回答by Chui Tey
PhoneGap has a decent Plugin API. You'd write the plugin in Java by implementing the IPlugin interface. Most of the magic is in the execute() function.
PhoneGap 有一个不错的插件 API。您可以通过实现 IPlugin 接口用 Java 编写插件。大多数魔法都在 execute() 函数中。
public interface IPlugin {
/**
* Executes the request and returns PluginResult.
*
* @param action The action to execute.
* @param args JSONArry of arguments for the plugin.
* @param callbackId The callback id used when calling back into JavaScript.
* @return A PluginResult object with a status and message.
*/
PluginResult execute(String action, JSONArray args, String callbackId);
// ... more ...
}
The best way to start writing a plugin is by writing the javascript API first. You would typical start by writing a custom javascript class, and in each method on the javascript class, marshal the variables and call into the plugin you developed using the Phonegap.exec() method. Here is the method signature for your reference.
开始编写插件的最佳方式是首先编写 javascript API。您通常会首先编写一个自定义 javascript 类,然后在 javascript 类的每个方法中,编组变量并调用您使用 Phonegap.exec() 方法开发的插件。这是方法签名供您参考。
/* src/com/phonegap/api/PluginManager.java */
/**
* Receives a request for execution and fulfills it by finding the appropriate
* Java class and calling it's execute method.
*
* PluginManager.exec can be used either synchronously or async. In either case, a JSON encoded
* string is returned that will indicate if any errors have occurred when trying to find
* or execute the class denoted by the clazz argument.
*
* @param service String containing the service to run
* @param action String containt the action that the class is supposed to perform. This is
* passed to the plugin execute method and it is up to the plugin developer
* how to deal with it.
* @param callbackId String containing the id of the callback that is execute in JavaScript if
* this is an async plugin call.
* @param args An Array literal string containing any arguments needed in the
* plugin execute method.
* @param async Boolean indicating whether the calling JavaScript code is expecting an
* immediate return value. If true, either PhoneGap.callbackSuccess(...) or
* PhoneGap.callbackError(...) is called once the plugin code has executed.
*
* @return JSON encoded string with a response message and status.
*/
@SuppressWarnings("unchecked")
public String exec(final String service, final String action,
final String callbackId, final String jsonArgs,
final boolean async)
You also need to register the Plugin. You do this by adding the registration code at the bottom of your custom javascript library.
您还需要注册插件。您可以通过在自定义 javascript 库的底部添加注册代码来完成此操作。
In the example below, the author defined a javascript BarcodeScanner class and registers it using the addConstructor method.
在下面的例子中,作者定义了一个 javascript BarcodeScanner 类并使用 addConstructor 方法注册它。
Two steps are carried out in the addConstructor:
在 addConstructor 中进行了两个步骤:
Create a new instance of BarcodeScanner in javascript and registers it. This is accessible in javascript as window.plugins.barcodeScanner
Registers the custom Plugin class with a service name. This service name is passed in as the first argument to PhoneGap.exec so that PhoneGap can instantiate the java plugin class and call the execute() method on it.
在 javascript 中创建一个 BarcodeScanner 的新实例并注册它。这可以在 javascript 中作为 window.plugins.barcodeScanner 访问
使用服务名称注册自定义插件类。该服务名称作为第一个参数传入 PhoneGap.exec 以便 PhoneGap 可以实例化 java 插件类并在其上调用 execute() 方法。
Sample registration code:
示例注册码:
PhoneGap.addConstructor(function() {
/* The following registers an instance of BarcodeScanner in window.plugins.barcodeScanner */
PhoneGap.addPlugin('barcodeScanner', new BarcodeScanner());
/* The following associates a service name BarcodeScanner with a class com.beetight.barcodescanner.BarcodeScanner */
/* The service name is the first argument passed into PhoneGap.exec */
PluginManager.addService("BarcodeScanner","com.beetight.barcodescanner.BarcodeScanner");
});
回答by Heladio Benicio
a simpler form:
更简单的形式:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
super.appView.getSettings().setJavaScriptEnabled(true);
super.appView.addJavascriptInterface(this, "MyCls");
super.loadUrl("file:///android_asset/www/login.html");
}
回答by Dhairya Vora
If anyone gets nullPointer exception using the code above, do super.oncreate() first and then super..init()
如果有人使用上面的代码得到 nullPointer 异常,先做 super.oncreate() 再做 super..init()
super.onCreate(savedInstanceState);
super.init();
I found this solution here: Phonegap Google Group
我在这里找到了这个解决方案:Phonegap Google Group
Thanks a lot to @zorglub76 for the solution....
非常感谢@zorglub76 的解决方案....
回答by Bodil
Communication from JavaScript to native is achieved by overriding the JavaScript prompt function in the Android native code and the message passed is much like that used in iOS. We used to use WebView.addJavascriptInterface to add Java objects directly to the JavaScript sandbox but that was causing some devices to crash with Android 2.3. To call JavaScript from native we currently use WebView.loadUrl(”javascript:…”) but that has some problems so we are soon moving over to polling a Java message queue calling a local HTTP server via a long-lived XHR connection.
JavaScript 与原生的通信是通过覆盖 Android 原生代码中的 JavaScript 提示函数来实现的,传递的消息与 iOS 中使用的非常相似。我们曾经使用 WebView.addJavascriptInterface 将 Java 对象直接添加到 JavaScript 沙箱,但这会导致一些设备在 Android 2.3 上崩溃。为了从本机调用 JavaScript,我们目前使用 WebView.loadUrl("javascript:...") 但这有一些问题,所以我们很快就会转向轮询 Java 消息队列,通过长期存在的 XHR 连接调用本地 HTTP 服务器。