加载中 ...
首页 > 常见问题 正文

干货|JNI实现机制

2019-03-24 10:31:08 来源:沈阳软件公司 作者:沈阳软件开发

文 / Mob 手艺专家 文军

 

说到JNI都不生疏,它的全称:Java Native Interface,即Java当地接口。

JNI不仅仅是Android特有的,它是属于Java平台的,它允许在Java虚拟机内运行的java代码与其他编程语言(如c, c++和汇编语言)编写的程序和库举行交互。

JNI挪用姿势:Java —> JNI —> C/C++(SO库)

在Android平台中,使用JNI封装了跟硬件相关的操作,从而可以通过Java挪用相关JNI模块,以到达对硬件的挪用。

 

下面我们将围绕如下内容举行睁开:

1.java代码编译和执行历程

2.jni通例使用姿势

3.so加载流程(jni执行流程、注册方式原理)

4.JNIEnv作用及实现

 

Java代码编译和执行历程

 

java代码编译和执行的历程涉及到两个下令:javac和java

1.首先通过javac编译java代码,天生class字节码文件

2.javacTestCode.java --> TestCode.class

3.然后通过java下令来执行class字节码

4.javaTestCode.class

java下令执行历程中,会先汇海虚拟机,加载TestCode类信息到内存,然后由执行引擎执行其main要领。

 

JVM的逻辑内存模子如下:

https://mmbiz.qpic.cn/mmbiz_png/yCBu7HSwemLwpc0MAnTeP1yn9gu14j3UyCVbJ5xOqFlmAcXzCnTSfc5IQm3FpUf3STwMeVicOt9RsgUKOzk4Z1g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

https://mmbiz.qpic.cn/mmbiz_jpg/yCBu7HSwemKib4cLfWfibGeM6h1c56tOhrIw5M28ntewRcsfBtnhraPdP7scSeTHMaWYIVe0Jomo0r7ZKBuZT44g/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

https://mmbiz.qpic.cn/mmbiz_jpg/yCBu7HSwemKib4cLfWfibGeM6h1c56tOhr5fbOsgG4ibsVWt4mov4ZKng3uToAXu7vKq5jKNXKcMQaqEXxmLZhNxQ/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

JNI通例使用姿势

 

1. 在java层通过native要害字建立当地要领,如下:(成员要领、static要领)

public class JNIMethods {

static {

System.loadLibrary("test-jni");

}

//隐式注册

public native String stringFromJNI();

public static native String testParams(int jint, String jstring, Object jobject, Object[] arrayObject, Listlist);

 

//显式注册

public native String stringFromJNIDis();

public static native String testParamsDis(int jint, String jstring, Object jobject, Object[] arrayObject, Listlist);

}

 

2. 建立c层代码,并注书籍地要领

#include

#include

#include "common.h"

 

jstring stringFromJNIDis(JNIEnv *env, jobject jobj);

jstring testParamsDis(JNIEnv *env, jclass type, jint jint_, jstring jstring_, jobject jobject_, jobjectArray objectArray, jobject list);

static jmethodID methodID_toString;

//显式注册

static JNINativeMethod gMethods[] = {

{"stringFromJNIDis", "()Ljava/lang/String;", (void *) stringFromJNIDis},

{"testParamsDis", "(ILjava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;Ljava/util/List;)Ljava/lang/String;", (void *) testParamsDis}

};

 

static int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int nMethods) {

jclass clazz;

clazz = env->FindClass(className);

if (clazz == NULL) {

return JNI_FALSE;

}

if (env->RegisterNatives(clazz, methods, nMethods) < 0) {

return JNI_FALSE;

}

return JNI_TRUE;

}

 

void appendString(JNIEnv *env, char *dest, jstring tmpStr) {

if (tmpStr == NULL) {

return;

}

const char *tmpString = env->GetStringUTFChars(tmpStr, 0);

strcat(dest, tmpString);

env->ReleaseStringUTFChars(tmpStr, tmpString);

}

 

//加载so时会执行该要领

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {

LOGD("test-jni.cpp JNI_OnLoad");

JNIEnv *env = NULL;

if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {

return -1;

}

if (NULL == env) {

return -1;

}

jclass clazz = env->FindClass("java/lang/Object");

methodID_toString = env->GetMethodID(clazz, "toString", "()Ljava/lang/String;");

//显式注书籍地要领

if (!registerNativeMethods(env, "com/mob/test/jni/testjni/JNIMethods", gMethods, NELEM(gMethods))) {

LOGE("test-jni.cpp JNI_OnLoad register JNIMethods failed");

}

return JNI_VERSION_1_4;

}

//卸载时会执行该要领

JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved) {

LOGD("test-jni.cpp JNI_OnUnload");

“沈阳软件公司”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与

我们联系删除或处理,客服QQ:55506560,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同

其观点或证实其内容的真实性。

推荐阅读