Android之JNI总结笔记
来源:互联网 发布:七天网络app官方下载 编辑:程序博客网 时间:2024/06/06 05:11
由于项目中的APP都是与硬件交互,所以难免会与Kernel层交互,但上层软件又是有Java语言编写的,怎么和C/C++语言交互呢?这里就使用到了JNI(Java Native Interface)。
Java如何调用JNI:
1.需要在Java中定义本地函数,使用关键字Native。
private native boolean jniopenserial()。
2.需要在Java中声明System.loadLibrary("本地库名称"),去让程序加载本地库。
3.在JNI中声明与Java对应的函数,并实现函数的功能。
static jboolean android_avin_openSerial(JNIEnv *env, jobject thiz){fdTtyS3 = open(SEND_DEV_NODE, O_RDWR|O_NOCTTY|O_NONBLOCK);if(fdTtyS3 < 0){ALOGE("open %s failed,fdTtyS3=%d(%d,%s)\n", SEND_DEV_NODE, fdTtyS3, errno, strerror(errno));return JNI_FALSE;}fdAudio = open(AUDIO_CTRL_NODE, O_RDWR|O_NOCTTY|O_NONBLOCK);if(fdAudio < 0) {ALOGE("open %s failed,fdAudio=%d(%d,%s)\n", AUDIO_CTRL_NODE, fdAudio, errno, strerror(errno));close(fdTtyS3);fdTtyS3 = -1;return JNI_FALSE;}return JNI_TRUE;}
4.将JNI本地函数与Java Native声明的函数进行映射
static JNINativeMethod sMethods[] = {{"jniopenserial","()Z", (void *)android_avin_openSerial},{"jniAvInSwitch", "(Z)Z", (void *)android_avin_switch},{"jniDVDSwitch", "(Z)Z", (void *)android_dvd_switch},{"jniDVDOperation", "(I)Z", (void *)android_dvd_operation},{"jnicloseserial", "()V", (void *)android_avin_closeSerial},};这个数组是什么时候被调用的呢?
首先我们需要知道Java中的System.loadLibray,它一般在类加载的时候或者构造函数之前被调用,经过层层关系,会调用到JNI的JNI_OnLoad函数:
jint JNI_OnLoad(JavaVM* vm, void* reserved){ UnionJNIEnvToVoid uenv; uenv.venv = NULL; jint result = -1; JNIEnv* env = NULL; ALOGI("JNI_OnLoad"); if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_6) != JNI_OK) { ALOGE("ERROR: GetEnv failed"); goto bail; } env = uenv.env; if (registerNatives(env) != JNI_TRUE) { ALOGE("ERROR: registerNatives failed"); goto bail; } result = JNI_VERSION_1_6;bail: return result;}
这个函数又会调用:
static int registerNatives(JNIEnv* env){ if (!registerNativeMethods(env, classPathName, sMethods, sizeof(sMethods) / sizeof(sMethods[0]))) { return JNI_FALSE; } return JNI_TRUE;}
这里我们看到了registerNativeMethods这个函数,并且发现了sMethods数组的身影。
/* * Register several native methods for one class. */static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* methods, int numMethods){ jclass clazz; clazz = env->FindClass(className); if (clazz == NULL) { ALOGE("Native registration unable to find class '%s'", className); return JNI_FALSE; } if (env->RegisterNatives(clazz, methods, numMethods) < 0) { ALOGE("RegisterNatives failed for '%s'", className); return JNI_FALSE; } return JNI_TRUE;}
通过上述调用关系我们可以知道,当加载本地库的时候,JNI和Java声明的本地函数就对应了起来。
JNI调用Java成员变量流程:
1.获取Java类
FindClass
2.获取成员变量的FieldID
GetFieldID
3.获取成员变量
GetXXXField
JNI调用Java对象:
1.获取Java类
FindClass/GetObjectClass
2.获取构造方法ID
GetMethodID
3 生成对象
NewObject
JNI改变Java成员变量值:
和JNI调用Java成员变量流程一样,只不过第三部变为SetXXXField
JNI调用Java方法
1.获取Java类或者对象
FindClass
2.获取方法的ID
GetMethodID
3.调用方法
CallXXXMethod
0 0
- Android之JNI总结笔记
- android学习笔记之JNI
- [JNI] Android JNI总结
- Android之JNI开发步骤总结
- android之JNI开发步骤总结
- android之JNI开发步骤总结
- Android基础总结之九:JNI
- android之JNI开发步骤总结
- android之JNI开发步骤总结
- android之JNI开发步骤总结
- android之JNI开发步骤总结
- android之JNI开发步骤总结
- android之JNI开发步骤总结
- Android之jni调用java函数总结
- android jni学习笔记之数据类型表
- Android Studio JNI使用之个人笔记
- Android开发笔记之Jni编程
- 学习笔记 android开发之JNI
- Android开发_Android系统构架
- 原来
- 使用Genymotion调试出现错误INSTALL_FAILED_CPU_ABI_INCOMPATI
- SSH启动过程中的问题
- .Net MVC4 上传大文件,并保存表单
- Android之JNI总结笔记
- 陀螺仪、加速度计讲解
- Ubuntu下locale文件
- 黑马程序员——关于异常
- Boost Geometry II
- 题目1510:替换空格
- 【CSS】transiction 搜索框
- STL源码剖析 - 第6章 算法 - 6.7.9 sort(排序算法)
- Linux下将源文件打包成JAR包并且使用