抛异常:
NDK c源码
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_example_fanenqian_ndk1_NDKtest_getString(JNIEnv *env, jclass type) {
return (*env)->NewStringUTF(env, "this is NDK application");
}
JNI方法
public class NDKtest {
public static native String getString();
static {
System.loadLibrary("ndk_mode");
}
}
很明显提示没有这个方法的实现
出现这个异常的原因是NDKtest类的包名一定要是com.example.fanenqian.ndk1,原因是JNI接口Java_com_example_fanenqian_ndk1_NDKtest_getString中,com_example_fanenqian_ndk1代表的是package name,NDKtest则是class name。所以该NDKtest包名必须是com_example_fanenqian_ndk1,类名是NDKtest,也就是说,我们.so中函数声明涉及到的package name和class name与调用它的package name和class name不符。因此我们要改变我们工程中的package name和class name。使其与.so文件中函数签名提示的一致,在这个类中加入native方法的声明。
JNI的命名规则
这里顺便说一下JNI的命名规则,对于传统的JNI编程来说,JNI方法跟Java类方法的名称之间有一定的对应关系,要遵循一定的命名规则,如下所示:
前缀: Java_类的全限定名,用下划线进行分隔(_):com_oyp_jni_JniTest
方法名:getTestString
JNI函数指定第一个参数: JNIEnv *
JNI函数指定第二个参数: jobject
实际Java参数: jstring, jint ….
所以对于在Java类 com.oyp.jni.JniTest类的一个方法:
public native String getTestString (String oyp);
其对应的jni层的方法如下:
jstring Java_com_oyp_jni_JniTest_getTestString(JNIEnv * e, jobject clazz, jstring oyp);
如果不这样命名,当把动态库加载进DVM的时候,通过JNIEnv *指针去查找Java Native方法对应的JNI方法的时候,就会找不到了。
注意,我们也可以利用函数注册的方法,将Java层的方法名跟JNI层的方法名的对应关系保存起来,注册到DVM中,就不需要这样的命名规范了。