GWT JSNI用于解决问题, 例如当我们需要将GWT与现有的手写JavaScript或与第三方JavaScript库集成时。有时, 我们需要访问GWT类API未公开的低级浏览器功能。
JSNI在网络上等同于内联汇编代码, 并且可以通过多种方式使用, 例如:
- 直接在JavaScript中实现Java方法。
- 将类型安全的Java方法签名包装在现有JavaScript周围。
- 从JavaScript代码调用到Java代码, 反之亦然。
- 跨Java / JavaScript边界引发异常。
- 从JavaScript读取和写入Java字段。
- 使用开发模式来调试Java源(使用Java调试器)和JavaScript(使用脚本调试器)。
【GWT JavaScript本机接口(JSNI)】句法
package com.xyz.client;
public class Alert {
public static native void alert(String msg) /*-{
$wnd.alert(msg);
}-*/;
}
从Java调用JSNI
从Java调用JSNI方法与调用常规Java方法没有什么不同。
例
button1.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
Alert.alert("clicked!");
}
});
调用者无法真正分辨出该方法是否是本机的。这为更改方法的实现方式提供了一定的灵活性。
从JSNI调用Java
这比从Java调用JSNI更为复杂。例如, 假设我们将一个对象传递给JSNI方法, 并且需要访问该对象中的字段或调用方法。我们需要知道GWT编译器如何管理Java字段和方法名称。它有助于从你自己的JavaScript代码访问字段。
访问Java字段
句法
obj.@class::field
哪里:
obj:这是被引用的对象实例。对于静态变量, 请省略实例表达式和尾随时间段。 class:这是在其中声明字段的类(或其子类)的完全限定名称。 field:这是要访问的字段的名称。
调用Java方法
调用方法使用与访问字段相似的语法, 除了还提供方法调用的签名。 Java方法可以重载, 即两个方法可以具有相同的名称, 但采用不同的参数。
句法
obj.@class::method(sig)(args)
哪里:
obj:它是被引用的对象实例。对于静态方法, 请省略实例表达式和尾随句点。 class:在此方法被声明(或其子类)。 method:它是被调用方法的名称。
GWT JSNI方法签名
JSNI方法签名与JNI方法签名完全相同, 只是方法返回类型被保留。下表显示了类型签名:
类型签名 | Java类型 |
---|---|
Z | Boolean |
B | Byte |
C | Char |
S | Short |
I | Int |
J | Long |
F | Float |
D | Double |
它演示了将数字, 字符串, 布尔值和Java对象传递到JavaScript中的方法。它还显示了JavaScript方法如何对传入的Java对象进行方法调用。
public class srcmini {
/** Pass a Java numeric primitive */
public static void testsrcminiNumeric() {
int x = 42;
jsNumeric(x);
}/**
* Method jsNumeric.
* @param x int
*/
private static native void jsNumeric(int x) /*-{
$wnd.alert(?x is ? + x);
}-*/;
/** Pass a Java String */
public static void testsrcminiString() {
String s = "my string";
jsString(s);
}/**
* Method jsString.
* @param s String
*/
private static native void jsString(String s) /*-{
$wnd.alert("s is " + s);
}-*/;
/** Pass a boolean */
public static void testsrcminiBoolean() {
boolean b = true;
jsBoolean(b);
}/**
* Method jsBoolean.
* @param b boolean
*/
private static native void jsBoolean(boolean b) /*-{
$wnd.alert("b is " + b);
}-*/;
/** Pass an arbitrary Java Object */
public static void testsrcminiObject() {
MyJavaObject obj = new MyJavaObject();
jsObject(obj);
}/**
* Method jsObject.
* @param obj MyJavaObject
*/
private static native void jsObject(MyJavaObject obj) /*-{
$wnd.alert("Calling getText(): " + obj.@MyJavaObject::getTextAt(I)(3));
}-*/;
}
下表包含JSNI代码中的数据类型和类型表示。
Java类型 | JavaScript代码显示 |
---|---|
Java Numeric | JavaScript数值, int var x = 5。 |
String | JavaScript字符串值var x =“ srcmini”。 |
Boolean | JavaScript布尔值var x = true。 |
JavaScriptObject | 必须源自JavaScript代码的JavaScriptObject。它应该是其他JSNI方法的返回值。 |
Java array | 一个不透明的值, 只能传递回Java代码。 |
Java对象 | 可以通过特殊语法访问的不透明值。 |