java反射回调函数_用J2V8注册Java回调函数

本教程介绍了如何使用J2V8将Java方法注册为JavaScript回调函数,允许在JavaScript中调用Java的方法。示例包括实现JavaCallback接口和反射注册方法,以及详细解释了参数传递和接收器的概念。
摘要由CSDN通过智能技术生成

J2V8是一套针对谷歌的V8 JavaScript引擎的Java绑定。J2V8的开发为Android平台带来了高效的Javascript的执行环境,taris.js 就是基于J2V8开发的。J2V8同时也可以运行在Windows、Linux、MacOS上。在上一个教程中我们已经学习了如何使用J2V8来执行Javascript脚本。在本教程中我们将演示如何用J2V8来注册Java回调函数。Java回调函数允许在Javascript中调用Java的方法。

回调函数

在Javascript中,函数是“第一类对象”,也就是说,函数也是对象,像其他对象一样可以被操作,可以被传递。使用J2V8可以将任何Javascript函数映射到Java的方法之上,当这些函数被调用时,J2V8实际上调用的是Java的方法,同时会将Javascript函数的参数传递给被调用的Java方法。

注册Java方法

可以用两种不同的方式将Java方法注册为Javascript回调函数。你可以选择实现JavaCallback 接口(或者是JavaVoidCallback 接口,如果这个函数不返回值的话),你也可以通过指明该函数签名来反射地将Java方法注册为Javascript回调函数。

JavaCallback

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脚本都可以向调用其他Javascript函数那样调用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');");

}

在上面这个例子中,一个现存对象中的方法被反射性地注册为一个Javascript回调函数。使用这种方法,在注册时必须明确指明Java对象,该对象需要被注册的方法以及该方法的所有的参数的类型的数组。

在第一个例子中,Java方法是直接注册到V8运行时环境本身上的,这就将一个函数放置在了一个全局作用域中。而在第二个例子中,那两个java方法是被注册到一个已经存在的名为“console”的Javascript对象上的。

参数

参数可以从Javascript中传递到Java方法中。如果一个Java方法是通过实现JavaCallback注册的,那么Javascript中的参数列表是通过一个V8Array传递的。这个V8Array包含了一些V8Object对象或者一些原始数据类型。这个V8Array本身是不需要开发者手动去释放它的,因为它不是由开发者创建的,然而,任何从这个V8Array中获取的作为参数的V8Object都需要手动的进行释放,因为它们是作为方法调用的结果返回给你的。

如果方法是通过反射的方式进行注册的,那么这个方法的所有的参数类型都是已知的。在这种情形下,传递给Javascript函数的参数必须与作为它的回调函数的Java方法的签名一致。

接收器

被调用的Javascript函数所在的对象会作为第一个参数被传递。请看以下示例:

var array1 = [{first:'Ian'}, {first:'Jordi'}, {first:'Holger'}];

for ( var i = 0; i < array1.length; i++ ) {

print.call(array1[i], " says Hi.");

}

在这种情形下,print 函数会被调用,并且会被在参数数组中被传递到Java回调函数中。不过,在这里,真正的Javascript对象也是很重要的。而V8Object则会作为receiver 传递。

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对象(译注:而一般的只是返回V8Object对象而已)。V8Function对象有一个call 方法,可以被用来从Java中调用Javascript的函数。

总结

在本教程中,我们学习了如何用J2V8将Java方法注册为Javascript的回调函数,并且从Javascript中调用它。

译者说明

本文大多数地方都采用直译,但是中文与英文之间的语言习惯的差异不可避免,技术文章也是如此,况且原文中很多概念和词句都是在一个隐含的上下文环境之中,如果直接翻译,那么就会显得非常突兀、晦涩,因此这种情况下不得不采用意译或者注释。不求“雅”,但力求“信”、“达”,已经力求准确,但奈何水平有限,难免会有所偏颇,望请海涵与指正,不甚感激。当然也十分欢迎各位来相互探讨研究。

另,以上全部代码已在Linux x86_64,部分代码在Android x86平台上进行测试,可以正常运行。

原文作者:Ian Bull

原文连接:http://eclipsesource.com/blogs/2015/06/06/registering-java-callbacks-with-j2v8/

译者:zyzz1995

联系方式:zyzz_work@163.com

本文只做学习交流使用,原文版权归原作者所有,在未取得相关授权的情况下请勿用于任何其他用途, 若要转载,请保留原文以及译文出处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值