首先澄清一个概念问题,NME中的JNI接口和java中的含义并不相同,java中的JNI是java调用本地C/C++代码的标准接口,而haXe中的JNI则正好相反,是用haXe在Android目标平台调用java代码。当然,意义上也说得通,因为从haXe和Android目标的关系来说,Android自带的java运行库反而是native的嘛,呵呵。
nme.JNI类的使用
haXe NME调用java方法是通过nme.JNI类实现的,JNI类中只有两个静态函数createStaticMethod和createMemberMethod。看看函数的说明:
/**
* Create bindings to an class instance method in Java
* @param className The name of the target class in Java
* @param memberName The name of the target method
* @param signature The JNI string-based type signature for the method
* @param useArray Whether the method should accept multiple parameters, or a single array with the parameters to pass to Java
* @return A method that calls Java. The first parameter is a handle for the Java object instance, the rest are passed into the method as arguments
*/
public static function createMemberMethod(className:String, memberName:String, signature:String, useArray:Bool = false):Dynamic;
/**
* Create bindings to a static class method in Java
* @param className The name of the target class in Java
* @param memberName The name of the target method
* @param signature The JNI string-based type signature for the method
* @param useArray Whether the method should accept multiple parameters, or a single array with the parameters to pass to Java
* @return A method that calls Java. Each argument is passed into the Java method as arguments
*/
public static function createStaticMethod(className:String, memberName:String, signature:String, useArray:Bool = false):Dynamic;
可以看到,参数列表完全一致,这两个函数的区别就在于,memberMethod在调用时,第一个参数必须是java对象的句柄(handler),它也就是java方法中的this引用。
具体的代码例子请看下面代码:
public static function getBuffer():Dynamic
{
if (_getBuffer_func == null)
_getBuffer_func = nme.JNI.createStaticMethod("com/company/product/HaxeStub", "getBuffer", "()[I", true);
var a = new Array<Dynamic>();
return _getBuffer_func(a);
}
上面的haXe函数将调用java类com.company.product.HaxeStub的静态方法"int[] getBuffer()"。
注意:
1. 类名中的'.'必须用'/'代替,NME自带的例程中这里写错了(那个例程已经很久没有更新了)。
2. 所谓signature就是java方法的签名,也就是方法原型的表述方式,这是Java虚拟机的标准。上面的方法签名说明getBuffer的原型是int[] getBuffer()。具体细节这里有篇不错的文章可以看看
3. createStaticMethod返回的Dynamic对象就可以当做一个普通的haXe函数来调用了,haXe会自动帮你对参数和返回值做java <-> haXe的转换。
4. 如果java方法的返回值是对象类型,你可以获得该对象的“句柄”(handler),你可以在haXe代码中传递句柄对象,也可以以它为参数调用其它java的静态方法或成员方法。
5. java类的构造方法也可以被调用,它实际上是作为一个名为"<init>"的普通静态方法处理的,返回值当然就是创建的新对象的句柄。"<init>"实际上也是构造方法在JVM中的标准名,对应的"<clinit>"则是类的静态初始化方法的标准名(就是java中 static { ... }这样的代码块,实际也是作为一个java静态方法处理的)。