使用J2V8注册Java回调
前言:本文章只是个人翻译自用,不喜欢者勿喷
最近在研究android与js交互
奈何本人能力有限,又是英语渣渣,特用机译方便理解
J2V8是Google流行的JavaScript引擎V8的一组Java绑定。 它的开发旨在将高效的JavaScript引入Android,并且是Tabris.js的主要力量。 J2V8也可以在Windows,Linux和Mac OS上运行。 在上一教程中,我们研究了如何使用J2V8执行JavaScript。 在本教程中,我们将演示如何向J2V8注册Java回调。 Java回调允许JavaScript调用Java方法。
回调
在JavaScript中,函数是一类对象,即它们是对象,可以像其他任何对象一样进行操纵和传递。使用J2V8,任何JavaScript函数都可以映射到Java方法。调用该函数时,J2V8将改为调用Java方法,并将JS参数传递给Java。
注册Java方法
Java方法可以两种不同方式注册为JS回调。您可以实现JavaCallback接口(或JavaVoidCallback如果方法不返回一个值),也可以通过指定其签名反思注册的方法。
Java回调
JavaVoidCallback callback = new JavaVoidCallback() {
public void invoke(final V8Object receiver, final V8Array parameters) {
if (parameters.length() > 0) {
Object arg1 = parameters.get(0);
System.out.println(arg1);
if (arg1 instanceof Releasable) {
((Releasable) arg1).release();
}
}
}
};
v8.registerJavaMethod(callback, "print");
v8.executeScript("print('hello, world');");
在此示例中,我们创建了一个实现
JavaVoidCallback的匿名类。此类的实例已在J2V8全局范围内注册,并被赋予名称print。 现在,执行的任何JavaScript都可以像调用其他JS函数一样调用print。
反思性地注册方法
class Console {
public void log(final String message) {
System.out.println("[INFO] " + message);
}
public void error(final String message) {
System.out.println("[ERROR] " + message);
}
}
public void start() {
Console console = new Console();
V8Object v8Console = new V8Object(v8);
v8.add("console", v8Console);
v8Console.registerJavaMethod(console, "log", "log", new Class<?>[] { String.class });
v8Console.registerJavaMethod(console, "err", "err", new Class<?>[] { String.class });
v8Console.release();
v8.executeScript("console.log('hello, world');");
}
在该示例中,现有对象的方法被反射地注册。必须指定Java对象,方法名称和参数列表。
在第一个示例中,Java方法是在V8运行时本身上注册的。这会将功能置于全局范围内。在第二个示例中,这些方法已在现有JavaScript对象(名为console)上注册。
争论
可以将参数从JavaScript传递到Java方法。如果该方法是通过实现JavaCallback注册的,则参数将作为V8Array传递。V8Array包含V8Object(或原语)。由于开发人员未实例化V8Array本身,因此不需要释放。但是,必须释放从参数列表中检索到的所有V8Object,因为它们是由于方法调用而返回给您的。
如果该方法是反射式注册的,则参数类型是已知的。在这种情况下,传递给JS函数的参数必须与Java方法签名匹配。
收件人
调用了该函数的JavaScript对象作为第一个参数传递。考虑以下JavaScript:
var array1 = [{first:'Ian'}, {first:'Jordi'}, {first:'Holger'}];
for ( var i = 0; i < array1.length; i++ ) {
print.call(array1[i], " says Hi.");
}
在这种情况下,将调用print方法,然后“ Hi说”。将在参数数组中传递。但是,实际的JS对象在这里也很重要。V8Object将作为接收者传递。
class PersonPrinter implements JavaVoidCallback {
@Override
public void invoke(final V8Object receiver, final V8Array parameters) {
System.out.println(receiver.getString("first") + parameters.get(0));
}
}
V8Function对象
在J2V8 3.0中,引入了V8Function对象。V8Function是V8Object的子类,只要从getObject调用返回函数,就将其返回。V8Function有一个调用方法,可用于从Java调用该函数。