我真的很难弄清楚如何使用JNI从Objective-C调用Java函数。
我首先要说的是,我对Java并不了解很多,但是对Obj- C非常熟悉。我有一个带有单个方法的Java类,需要从我的应用程序包中调用它。该jar位于包中的Resources文件夹内,并且我将其NSJavaRoot设置为Content/Resources,它NSJavaNeeded被检查并NSJavaPath包含2个jar文件的名称(主要是一个,一个依赖)。
NSJavaRoot
Content/Resources
NSJavaNeeded
NSJavaPath
我正在通过调用来启动虚拟机JNI_CreateJavaVM,然后尝试使用该类来查找类,NSClassFromString这是错的,但这是我在搜索中找到的唯一方法。我相信使用不推荐使用的Java桥时此方法是正确的,但是我找不到使用JNI的任何示例或参考。
JNI_CreateJavaVM
NSClassFromString
我的Java类如下所示:
package foo; public class bar { public function dostuff() { } }
我需要dostuff()在应用程序流程中致电一次。有谁知道如何做到这一点?
dostuff()
谢谢,J
由于不推荐使用JavaBridge,因此您将必须使用JNI来完成所有这些工作。在MacOS上,您需要将JavaVM.framework添加到您的项目中,并且从源文件中查找的标头是:
#import <JavaVM/jni.h>
接下来,您需要设置JavaVM。根据您的类路径和其他要求,这可能很简单,但是您在正确的道路上,因为这是您用来创建JVM的功能:
JNI_CreateJavaVM(JavaVM **pJVM, void **pJNIEnv, void *args);
接下来,您将希望获得对类foo.bar的引用。您可以使用从JNI_CreateJavaVM传递的pJNIEnv来完成此操作。您将要致电:
jclass myClass = JNIEnv->FindClass(JNIEnv, "foo/bar"); // Note the slashes replacing the dots...
假设一切设置正确,您将获得对您的课程的引用。假设foo.bar具有默认的无参数构造函数,您可以获取它的一个实例,如下所示:
jobject myFooBar = JNIEnv->NewObject(JNIEnv, myClass);
现在,您需要获取doStuff方法的methodID。为此,您将需要它的方法签名,可以通过调用javap来获得它,如下所示:
% javap -s foo.bar
应该产生如下输出:
Compiled from "bar.java" public class foo.bar extends java.lang.Object{ public foo.bar(); Signature: ()V public void doStuff(); Signature: ()V }
然后,您可以使用它来获取methodID,您需要对其进行调用。像这样:
jmethodID mid = JNIEnv->GetMethodID(JNIEnv, myClass, "doStuff", "()V");
假设所有这些都做对了,那么您可以像下面这样调用方法:
JNIEnv->CallVoidMethod(JNIEnv, myFooBar, mid);
并且该方法应被调用。在任何这些阶段之后,您可能希望与VM进行检查,以查看是否存在异常。您可以通过执行以下操作检查是否发生了异常:
if (JNIEnv->ExceptionCheck(JNIEnv)) { // Handle the exception... }
如果您想要实际的throwable,可以使用ExceptionOccurred JNI方法获取它。
因此,最重要的是:如何使用JNI从Cocoa调用Java方法。您将需要阅读JNI文档,特别是有关了解全局引用和本地引用之间差异的部分。(即,使您的Cocoa侧引用的持续时间足够长,可以在创建它们的范围之外被调用。)实际上,有一整章介绍了常见的错误和陷阱,您会遇到很多错误和陷阱。
http://java.sun.com/docs/books/jni/
祝好运!