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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 儿子曰他妈免费视频 夏目彩春中文字幕父 被儿子不良的同学侵犯中文字幕 夏目彩春不速之客中文字幕 上司侵犯夏目彩春下载链接 健身教练夏目彩春 边打电话边被侵犯中文字幕 一个女的在厨房被水电工侵犯 中文字幕侵犯上司影音先锋 希岛爱理视频水电工侵犯 夏日彩春经典作品视频 被水电工掠夺的妻子 多爱井野再次被水电工 维修工强家庭主妇 满员电车大腿颤抖3 公交汉痴未删减版 弟弟的妻子在线播放 妻子被修空调的白玩了一下午 pz505被水电工侵 中文字幕侵犯妻子 妻子被楼下修理工白玩 边打电话边骗她老公在跑步 中山理莉 中文字幕 在线播放 白石利奈 在线 20岁女孩被四个强壮男电影 边打电话边做女客服中文版 电车侵扰bd 被夫侵犯bd 中文字幕边打电话边做 白石茉利奈star-782 在丈夫面前被别人犯侵天翼电影 中文版丈夫的上司连续浸七天 吉尺明步110部连接 吉g明教师步中文字迅雷下载 吉次明涉作品 被丈夫好友侵犯有感觉了中文3 侵犯新娘在丈夫面前被侵先锋 吉朋步高清在线 吉译朋步查官 新娘在婚礼上的厕所被动态 在丈夫遗像面前被侵演员叫什么