GWT JavaScript本机接口(JSNI)

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
GWT JSNI示例
它演示了将数字, 字符串, 布尔值和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对象 可以通过特殊语法访问的不透明值。

    推荐阅读