在JNI Android中调用构造函数失败

时间:2012-02-15 01:19:30

标签: android android-ndk java-native-interface

我试图从我的JNI Android代码中调用构造函数;但不知怎的,它失败了以下例外.. 我相信我错过了一些非常小的东西;但是我无法弄清楚......任何人都可以指出吗?

 02-14 16:56:56.689: W/dalvikvm(397): JNI WARNING: JNI method called with exception raised
 02-14 16:56:56.710: W/dalvikvm(397):              in Lpv/ndk/Employee;.createWithAge (I)Lpv/ndk/Employee; (GetMethodID)

 02-14 16:56:56.710: W/dalvikvm(397): Pending exception is:
 02-14 16:56:56.710: I/dalvikvm(397): Ljava/lang/NoClassDefFoundError;: pv.ndk.Employee;
 02-14 16:56:56.723: I/dalvikvm(397):   at pv.ndk.Employee.createWithAge(Native Method)

 02-14 16:56:56.740: I/dalvikvm(397): Caused by:
 02-14 16:56:56.740: I/dalvikvm(397): Ljava/lang/ClassNotFoundException;: pv.ndk.Employee; in loader dalvik.system.PathClassLoader[/data/app/pv.ndk-2.apk]

这是我的代码:

Employee类有2个构造函数和一个返回年龄的方法

Employee()
Employee(int age)
int getAge();

令人惊讶的是,当我调用方法getAge()时...调用通过并获取年龄...但是当我尝试调用“Employee构造函数”然后尝试getAge()时抛出此异常...

某种程度上无法找到这个类: 我尝试了GetObjectClass()

所遇到的所有可能性 这是有效的;当我在调用

中传递Employee对象时
JNIEXPORT jint JNICALL Java_pv_ndk_Employee_getAgeC(JNIEnv *env, jobject callingObject, jobject employeeObject) 
{
jclass employeeClass = env->GetObjectClass(employeeObject);
jmethodID midGetName = env->GetMethodID(employeeClass, "getAge", "()I");
int age =  env->CallIntMethod(employeeObject, midGetName);
//other code
}

这不起作用;我不确定为什么它找不到这个班级.. 我试过“Lpv / ndk / Emploee”“LEmployee”“pv / ndk / Employee”..甚至尝试过以下方法:

jclass localRefCls = env->FindClass("pv/ndk/Employee");
jclass clazzEmployee = (_jclass*)env->NewGlobalRef(localRefCls);
JNIEXPORT jobject JNICALL Java_pv_ndk_Employee_createWithAge(JNIEnv *env, jobject callingObject, jint age) {
jclass employeeClass = env->FindClass("pv/ndk/Employee");
jmethodID midConstructor = env->GetMethodID(employeeClass, "<init>", "(I)V"); // BOOM SCREWED HERE .. !!
}

但每次我的代码都来到env-&gt; GetMethodID - vm Aborts ...

2 个答案:

答案 0 :(得分:0)

令人惊讶的是,相同的代码今天起作用:)

可能与我部署代码的方式有关...我相信&#34;自动构建&#34;应该照顾它...真的很遗憾在这里制作一个关于工作代码片段的混淆......我是NDK和JNI开发的新手......

这肯定有效

jclass employeeClass = env->FindClass("pv/ndk/Employee");
//constructor call depicted by <init> and it's parameters (I) and return type V
jmethodID midConstructor = env->GetMethodID(employeeClass, "<init>", "(I)V");

我认为原因可能与&#34;本地共享库&#34;新修改后没有部署...这些是我过去遵循的步骤: [1]我重建了#34;共享库&#34;随着修改;使用&#34; ndk-build&#34; __ [2]然后我在我的设备上部署了android项目

但似乎Eclipse缓存了&#34;库&#34; ??? [如果我错了,请纠正我] 因此,这些变化被考虑在内......

解决方案:[可能]

[1]我重建了库__ [2]我清理了整个项目__ [3]然后在设备上部署了项目......

答案 1 :(得分:0)

FindClass方法需要完整的类签名。 注意:如果你有任何内部类/将无法工作,你必须使用$ 例如,如果你的包名是A.B.C而你的主类名是D而你的子类名是E那么你必须使用FindClass(“LA / B / C / D $ E;”);