在 JNI Android 中调用构造函数失败
我正在尝试从 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 个构造函数和一个方法,当我调用方法 getAge() 时,该方法会令人惊讶地返回年龄
Employee()
Employee(int age)
int 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->GetMethodID - vm 中止...
I am trying to call a constructor from my JNI Android code; but somehow it fails with the following exception..
I am sure I am missing something really small ; but I am not able to figure out ... can anyone please point out ?
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]
Here is my code :
Employee class has 2 constructors and a method to return the age
Employee()
Employee(int age)
int getAge();
suprisingly when I invoke the method getAge()..the call goes through and fetches the age... But when I try to call the "Employee constructor" and then try to getAge() this exception is thrown...
somehow It is not able to find the class:
I have tried with all the possiblities I came across for GetObjectClass()
this works ; when I pass the Employee object in the call
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
}
THIS DOES NOT WORK ; I am not sure why it is not able to find the class..
I have tried with "Lpv/ndk/Emploee" "LEmployee" "pv/ndk/Employee" .. and even tried with the following approach:
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 .. !!
}
But everytime my code comes to env->GetMethodID - the vm Aborts ...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
令人惊讶的是,相同的代码今天可以工作:)
可能与我部署代码的方式有关...我相信“自动构建”应该已经解决了它...真的很抱歉在这里造成了关于工作代码的混乱片段...我是 NDK 和 JNI 开发的新手...
这绝对有效,
我认为原因可能与新修改后未部署的“本机共享库”有关...这些是我用来执行的步骤跟随 :
[1] 我通过修改重新构建了“共享库”;使用“ndk构建”
__[2] 然后我在我的设备上部署 android 项目
,但似乎 Eclipse 缓存了“库”??? [如有错误请指正]
因此,考虑到了这些更改...
解决方案:[可能]
[1] 我重建了库 __ [2] 我清理了整个项目 __ [3] 然后在设备上部署了该项目...
surprisingly the same code works today :)
probably it had to do with the way I was deploying the code... I believed that "auto build" should have taken care of it... Really sorry for creating confusion here regarding a working code snippet... I am new to NDK and JNI development ...
This definately works
I think the reason might have to do with the "native shared-library" not getting deployed after new modification... These are the steps I used to follow :
[1] I re-built the "Shared-library" with the modification ; using the "ndk-build"
__[2] Then I deploy the android project on my device
but seems Eclipse caches the "library" ??? [ please correct me if I am wrong ]
Hence the changes were taken into account...
Solution : [ possibly ]
[1] I rebuilt the library __ [2] I cleaned the whole project __ [3] then deployed the project on device...
FindClass 方法需要完整的类签名。
注意:如果你有任何内部类/不起作用,你必须使用 $
例如,如果您的包名称是 ABC,主类名称是 D,子类名称是 E,那么您必须使用 FindClass("LA/B/C/D$E;");
FindClass method needs full class signature.
Note:if you have any inner classes / will not work,you have to use $
for example if your package name is A.B.C and your main class name is D and your subclass name is E then you have to use FindClass("LA/B/C/D$E;");