JNI和NDK笔记

 JNI与NDK
 JNIEnv jobject对象 访问Java对象 保存对java对象的引用    静态方法 第二个参数是jclass类
 jstring 是java本地类型,占用16位,C语言中字符串仅占用8位.
 javah -jni HelloJNI
 g++ -shared -I /usr/java/jdk1.5.0_22/include/ -I /usr/java/jdk1.5.0_22/include/linux/ HelloJNI.h -o hellojni.so
 这是因为在jni.h中引用了jni_md.h头文件,该头文件和jni.h不在一个目录下,所以我们还需要再指定jni_md.h的目录
 Either change the C variants like
(*env)->FindClass(env, ...)
to the C++ variants, like
env->FindClass(...)
在C++文件中使用JNIEnv* env变量,直接使用env->即可
JNI就是java通过java虚拟机调用C函数
在C端 创建java对象,访问类静态成员,调用类静态方法
查找待访问的成员变量的java类的jclass值
若想获取指定类的jclass值,调用JNI函数FindClass即可
成员变量的ID保存在jfieldID类型的变量中
GetStaticFieldID(clazz,"staticIntField","I"); C++
GetStaticFieldID(env,clazz,"staticIntField","I");c env要加上
若获取构造方法的ID,方法名为<init>  JNI函数NewObject
局部引用  NewGlobalRef 生成全局引用
获取ID的时候传入的都是类jclass
GetObjectClass返回类引用  静态要加上static
invocation API   
GetStringUTFChars() 将JNI中的jstring转换成 c/c++字符串
NewStringUTF 将字符串转换成jstring
env指向JNI接口指针  可以调用JNI函数 CreateJavaVM 返回值为0 成功
FindClass装载Java类
NewStringUTF将UTF-8形式的C字符串转换成java字符串
包含的文件jni.h/include和jni_md.h/include/win32 java虚拟机的库文件/lib/jvm.lib
app_process的C++本地应用程序调用JNI Invocation API启动运行
app_process 会先初始化Android runtime,然后运行Zygote进程 ZygoteInit类组成 app_process然后调用ZygoteInit 类的main方法,从而运行Zygote进程   Java虚拟机加载的时候,库中查找java本地方法拥有相同签名的本地函数,若一致,则将本地函数映射到JNI本地函数
解决本地加载缓慢的问题,RegisterNatives()的JNI函数,允许开发者将JNI本地函数与Java类的本地方法直接映射在一起
Java虚拟机检查命名规范 多了的话会很缓慢 如果库中JNI_OnLoad(手工映射 需要在 这个方法中调用RegisterNatives)被实现,Java虚拟机就不会进行匹配了
System.LoadLibrary方法被调用时,会调用JNI_OnLoad
GetEnv 判断java虚拟机是否支持指定的JNI版本,然后将JNI接口指针设置到*env中
Java类的本地方法和JNI本地函数映射在一起
在Android系统中使用JNI_Onload函数直接映射本地方法  system server运行各种服务
LOCAL_SRC_FILES源码文件 LOCAL_MODULE库
register_android_server_
jniRegisterNativeMethods//JNIHelp.h中dalvik/libnativehelper/include/nativehelper/
实现在JNIHelp.c中
最终调用(*env)->RegisterNatives(env, clazz, gMethods, numMethods)
libc c头文件  libm 数学库头文件 liblog log库头文件
class file has wrong version 50.0, should be 49.0
Please remove or make sure it appears in the correct subdirectory of the classpath.
java版本不对 49对于java 5 50对于java 6
javah -jni com.example.ndkexam.NDKExam
进入应用根目录 然后执行ndk-build命令,自动编译,生成本地库

猜你喜欢

转载自blog.csdn.net/jiyilanzhou/article/details/51914185