Android系统学习总结之深入理解JNI

深入理解JNI

  1. JNI,javanativeinterface,java本地调用,Java程序中的函数可以调用native语言(C/C++)写的函数,Native函数可以调用Java层函数。
  2. 加载JNI库
    System.loadLibrary("media_jni");//加载对应的JNI库
  3. 声明由关键字native修饰的函数
private static native final void native_init();
private native boolean processFile(Stringpath,StringmimeType,MediaScannerClientclient);
  1. JNI的静态注册方法:
    a) 先编写Java代码,然后编译生成.class文件;
    b) 使用javah,如javah-ooutputpackagename.classname,这样就会生成一个叫output.h的JNI层头文件。其中packagename.classname是java代码编译后的class文件,而在生成的output.h文件里,声明了对应的JNI层函数,只要实现里面的函数即可.
  2. JNIEnv是一个与线程相关的代表JNI环境的结构体,提供了一些JNI系统函数,通过这些函数可以:
    a) 调用Java的函数;
    b) 操作jobject对象等很多事情;
  3. JavaVM和JNIEnv的关系:
    a) 调用JavaVM的AttachCurrentThread函数,就可以得到这个线程的JNIEnv结构体。这样就可以在后台线程中回调Java函数了。
    b) 在后台线程退出前,需要调用JavaVM的DetachCurrentThread函数来释放对应的资源。
  4. jfieldID和jmethodID来表示Java类的成员变量和成员函数。通过下面两个函数得到:
jfieldID GetFieldID(jclassclazz,constchar*name,constchar*sig);
jmethodID GetMethodID(jclassclazz,constchar*name,constchar*sig);

其中,jclass代表Java类,那么表示成员函数或成员变量的名字,sig为这个函数和变量的签名信息。
8. 调用JNIEnv的NewString(JNIEnvenv,constjcharunicodeChars,jsizelen),可以从Native的字符串得到一个jstring对象,其实,可以把一个jstring对象看成是Java中String对象在JNI层的代表,jstring就是一个JavaString,但由于JavaString存储的是Unicode字符串,所以NewString函数的参数必须是Unicode字符串。
9. 调用JNIEnv的NewStringUTF将根据Native的一个UTF-8字符串得到一个jstring对象。
10. GetStringChars函数和GetStringUTFChars函数,可以将JavaString对象转换成本地字符串。其中GetStringChars得到一个Unicode字符串,而GetStringUTFChars得到一个UTF-8字符串。
11. 调用上面几个函数后,需要调用ReleaseStringCHars函数或ReleaseStringUTFChars函数来对应地释放资源,否则绘导致JVM内存泄漏。
12. Java提供一个叫javap的工具额能帮助生成函数或变量的签名信息:
javap-s-pxxx
xxx为编译后的class文件,s表示输出内部数据类型的签名信息,p表示打印所有函数和成员的签名信息,默认只会打印public成员和函数的签名信息。
13. JNI层函数可以在代码中截获和修改这些异常,JNIEnv提供三个函数给予帮助:
a) ExceptionOccured函数,用来判断是否发生异常;
b) ExceptionClear函数,用来清理当前JNI层中发生的异常;
c) ThrowNew函数,用来向Java层抛出异常。

发布了39 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43443900/article/details/103238429