JNI层方法命名规范

在java层对应的native方法的声明,test方法是一个本地方法,其参数是字符串类型,返回值是字符串类型。

package com.kltz88.jnidemo;public class Test {    static {        System.loadLibrary("test");    }    public native String test(String name);}

由android studio自动生成的native层的方法如下。

#include <jni.h>JNIEXPORT jstring JNICALLJava_com_kltz88_car_jnidemo_Test_test(JNIEnv *env, jobject instance, jstring name_) {    const char *name = (*env)->GetStringUTFChars(env, name_, 0);    // TODO    (*env)->ReleaseStringUTFChars(env, name_, name);    return (*env)->NewStringUTF(env, returnValue);}

函数的命名规则

函数命名规则为:Java_类全路径方法名。如Java_com_kltz88_jnidemo_Test_test,其中Java是函数的前缀,com_kltz88_jnidemo_Test是类名,test是方法名,它们之间用 _(下划线) 连接。

函数参数

JNIEXPORT jstring JNICALL Java_com_kltz88_jnidemo_Test_test(JNIEnv *, jclass, jstring );
- 第一个参数:JNIEnv* 是定义任意native函数的第一个参数(包括调用JNI的RegisterNatives函数注册的函数),指向JVM函数表的指针,函数表中的每一个入口指向一个JNI函数,每个函数用于访问JVM中特定的数据结构。
- 第二个参数:调用java中native方法的实例或Class对象,如果这个native方法是实例方法,则该参数是jobject,如果是静态方法,则是jclass
- 第三个参数:Java对应JNI中的数据类型,Java中String类型对应JNI的jstring 类型。

函数返回值类型

夹在JNIEXPORT和JNICALL宏中间的jstring ,表示函数的返回值类型,对应Java的void类型

JAVA层与JNI层数据类型的对应

下面是一个测试方法

public native void test(char c,short s,byte by,int i,long l,float f,double d,boolean b,String str,Object o,Test t,int[] arr);

jni层面生成的函数原型

JNIEXPORT void JNICALLJava_com_kltz88_car_jnidemo_Test_test(JNIEnv *env, jobject instance, jbyte by, jchar c, jshort s, jint i,                                      jlong l, jfloat f, jdouble d, jboolean b, jstring str_,                                      jobject o, jobject t, jintArray arr);

我们会发现基本数据类型直接会有一种对应关系

其实只是使用了typedef重新定义了一下

typedef unsigned char   jboolean;       /* unsigned 8 bits */typedef signed char     jbyte;          /* signed 8 bits */typedef unsigned short  jchar;          /* unsigned 16 bits */typedef short           jshort;         /* signed 16 bits */typedef int             jint;           /* signed 32 bits */typedef long long       jlong;          /* signed 64 bits */typedef float           jfloat;         /* 32-bit IEEE 754 */typedef double          jdouble;        /* 64-bit IEEE 754 */

进一步还会发现,引用类型也存在一定的对应关系

也是通过typedef重新定义了一下,都是一个指针

typedef void*           jobject;typedef jobject         jclass;typedef jobject         jstring;typedef jobject         jarray;typedef jarray          jobjectArray;typedef jarray          jbooleanArray;typedef jarray          jbyteArray;typedef jarray          jcharArray;typedef jarray          jshortArray;typedef jarray          jintArray;typedef jarray          jlongArray;typedef jarray          jfloatArray;typedef jarray          jdoubleArray;typedef jobject         jthrowable;typedef jobject         jweak;

方法签名

字段描述

值得注意的是
- 类是使用L全限定名;,比如String, 其签名为Ljava/lang/util/String;
- 数组是使用[类型签名, 比如 [B

方法描述

JNI层暴露的方法

    jint        (*GetVersion)(JNIEnv *);    jclass      (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,                        jsize);    jclass      (*FindClass)(JNIEnv*, const char*);    jmethodID   (*FromReflectedMethod)(JNIEnv*, jobject);    jfieldID    (*FromReflectedField)(JNIEnv*, jobject);    /* spec doesn't show jboolean parameter */ jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); jclass (*GetSuperclass)(JNIEnv*, jclass); jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); /* spec doesn't show jboolean parameter */    jobject     (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);    jint        (*Throw)(JNIEnv*, jthrowable);    jint        (*ThrowNew)(JNIEnv *, jclass, const char *);    jthrowable  (*ExceptionOccurred)(JNIEnv*);    void        (*ExceptionDescribe)(JNIEnv*);    void        (*ExceptionClear)(JNIEnv*);    void        (*FatalError)(JNIEnv*, const char*);    jint        (*PushLocalFrame)(JNIEnv*, jint);    jobject     (*PopLocalFrame)(JNIEnv*, jobject);    jobject     (*NewGlobalRef)(JNIEnv*, jobject);    void        (*DeleteGlobalRef)(JNIEnv*, jobject);    void        (*DeleteLocalRef)(JNIEnv*, jobject);    jboolean    (*IsSameObject)(JNIEnv*, jobject, jobject);    jobject     (*NewLocalRef)(JNIEnv*, jobject);    jint        (*EnsureLocalCapacity)(JNIEnv*, jint);    jobject     (*AllocObject)(JNIEnv*, jclass);    jobject     (*NewObject)(JNIEnv*, jclass, jmethodID, ...);    jobject     (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);    jobject     (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);    jclass      (*GetObjectClass)(JNIEnv*, jobject);    jboolean    (*IsInstanceOf)(JNIEnv*, jobject, jclass);    jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);    jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);    jobject     (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);    jboolean    (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jboolean    (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jbyte       (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);    jbyte       (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jbyte       (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jchar       (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);    jchar       (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jchar       (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jshort      (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);    jshort      (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jshort      (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);    jint        (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jint        (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jlong       (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);    jlong       (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);    jlong       (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jfloat      (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;    jfloat      (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;    jfloat      (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;    jdouble     (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...) __NDK_FPABI__;    jdouble     (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list) __NDK_FPABI__;    jdouble     (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*) __NDK_FPABI__;    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);    void        (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);    void        (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);    jobject     (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jobject     (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    jobject     (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jboolean    (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jboolean    (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,                         jmethodID, va_list);    jboolean    (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,                         jmethodID, jvalue*);    jbyte       (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jbyte       (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    jbyte       (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jchar       (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jchar       (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    jchar       (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jshort      (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jshort      (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    jshort      (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jint        (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jint        (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    jint        (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jlong       (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    jlong       (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    jlong       (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jfloat      (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...) __NDK_FPABI__;    jfloat      (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list) __NDK_FPABI__;    jfloat      (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*) __NDK_FPABI__;    jdouble     (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...) __NDK_FPABI__;    jdouble     (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list) __NDK_FPABI__;    jdouble     (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*) __NDK_FPABI__;    void        (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,                        jmethodID, ...);    void        (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,                        jmethodID, va_list);    void        (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,                        jmethodID, jvalue*);    jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);    jobject     (*GetObjectField)(JNIEnv*, jobject, jfieldID);    jboolean    (*GetBooleanField)(JNIEnv*, jobject, jfieldID);    jbyte       (*GetByteField)(JNIEnv*, jobject, jfieldID);    jchar       (*GetCharField)(JNIEnv*, jobject, jfieldID);    jshort      (*GetShortField)(JNIEnv*, jobject, jfieldID);    jint        (*GetIntField)(JNIEnv*, jobject, jfieldID);    jlong       (*GetLongField)(JNIEnv*, jobject, jfieldID);    jfloat      (*GetFloatField)(JNIEnv*, jobject, jfieldID) __NDK_FPABI__;    jdouble     (*GetDoubleField)(JNIEnv*, jobject, jfieldID) __NDK_FPABI__;    void        (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);    void        (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);    void        (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);    void        (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);    void        (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);    void        (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);    void        (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);    void        (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat) __NDK_FPABI__;    void        (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble) __NDK_FPABI__;    jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);    jobject     (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);    jobject     (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);    jobject     (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jboolean    (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);    jboolean    (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,                        va_list);    jboolean    (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,                        jvalue*);    jbyte       (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);    jbyte       (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);    jbyte       (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jchar       (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);    jchar       (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);    jchar       (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jshort      (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);    jshort      (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);    jshort      (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jint        (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);    jint        (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);    jint        (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jlong       (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);    jlong       (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);    jlong       (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jfloat      (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...) __NDK_FPABI__;    jfloat      (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__;    jfloat      (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__;    jdouble     (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...) __NDK_FPABI__;    jdouble     (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list) __NDK_FPABI__;    jdouble     (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*) __NDK_FPABI__;    void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);    void        (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);    void        (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);    jfieldID    (*GetStaticFieldID)(JNIEnv*, jclass, const char*,                        const char*);    jobject     (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);    jboolean    (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);    jbyte       (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);    jchar       (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);    jshort      (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);    jint        (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);    jlong       (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);    jfloat      (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID) __NDK_FPABI__;    jdouble     (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID) __NDK_FPABI__;    void        (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);    void        (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);    void        (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);    void        (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);    void        (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);    void        (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);    void        (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);    void        (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat) __NDK_FPABI__;    void        (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble) __NDK_FPABI__;    jstring     (*NewString)(JNIEnv*, const jchar*, jsize);    jsize       (*GetStringLength)(JNIEnv*, jstring);    const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);    void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);    jstring     (*NewStringUTF)(JNIEnv*, const char*);    jsize       (*GetStringUTFLength)(JNIEnv*, jstring);    /* JNI spec says this returns const jbyte*, but that's inconsistent */ const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); jsize (*GetArrayLength)(JNIEnv*, jarray); jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); jbyteArray (*NewByteArray)(JNIEnv*, jsize); jcharArray (*NewCharArray)(JNIEnv*, jsize); jshortArray (*NewShortArray)(JNIEnv*, jsize); jintArray (*NewIntArray)(JNIEnv*, jsize); jlongArray (*NewLongArray)(JNIEnv*, jsize); jfloatArray (*NewFloatArray)(JNIEnv*, jsize); jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*, jint); void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, jbyte*, jint); void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, jchar*, jint); void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, jshort*, jint); void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, jint*, jint); void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, jlong*, jint); void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, jfloat*, jint); void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, jdouble*, jint); void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, jsize, jsize, jboolean*); void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, jsize, jsize, jbyte*); void (*GetCharArrayRegion)(JNIEnv*, jcharArray, jsize, jsize, jchar*); void (*GetShortArrayRegion)(JNIEnv*, jshortArray, jsize, jsize, jshort*); void (*GetIntArrayRegion)(JNIEnv*, jintArray, jsize, jsize, jint*); void (*GetLongArrayRegion)(JNIEnv*, jlongArray, jsize, jsize, jlong*); void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, jsize, jsize, jfloat*); void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, jsize, jsize, jdouble*); /* spec shows these without const; some jni.h do, some don't */    void        (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,                        jsize, jsize, const jboolean*);    void        (*SetByteArrayRegion)(JNIEnv*, jbyteArray,                        jsize, jsize, const jbyte*);    void        (*SetCharArrayRegion)(JNIEnv*, jcharArray,                        jsize, jsize, const jchar*);    void        (*SetShortArrayRegion)(JNIEnv*, jshortArray,                        jsize, jsize, const jshort*);    void        (*SetIntArrayRegion)(JNIEnv*, jintArray,                        jsize, jsize, const jint*);    void        (*SetLongArrayRegion)(JNIEnv*, jlongArray,                        jsize, jsize, const jlong*);    void        (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,                        jsize, jsize, const jfloat*);    void        (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,                        jsize, jsize, const jdouble*);    jint        (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,                        jint);    jint        (*UnregisterNatives)(JNIEnv*, jclass);    jint        (*MonitorEnter)(JNIEnv*, jobject);    jint        (*MonitorExit)(JNIEnv*, jobject);    jint        (*GetJavaVM)(JNIEnv*, JavaVM**);    void        (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);    void        (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);    void*       (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);    void        (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);    const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);    void        (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);    jweak       (*NewWeakGlobalRef)(JNIEnv*, jobject);    void        (*DeleteWeakGlobalRef)(JNIEnv*, jweak);    jboolean    (*ExceptionCheck)(JNIEnv*);    jobject     (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);    void*       (*GetDirectBufferAddress)(JNIEnv*, jobject);    jlong       (*GetDirectBufferCapacity)(JNIEnv*, jobject);    /* added in JNI 1.6 */    jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);

JNI层访问和修改JAVA实例变量与静态变量

由于JNI函数是直接操作JVM中的数据结构,不受Java访问修饰符的限制。即,在本地代码中可以调用JNI函数可以访问Java对象中的非public属性和方法

访问和修改实例变量操作步聚

  1. 调用GetObjectClass函数获取实例对象的Class引用
  2. 调用GetFieldID函数获取Class引用中某个实例变量的ID
  3. 调用GetXXXField(如GetObjectField)函数获取变量的值,需要传入实例变量所属对象和变量ID
  4. 调用SetXXXField(如SetObjectField)函数修改变量的值,需要传入实例变量所属对象、变量ID和变量的值

访问和修改静态变量操作步聚

  1. 调用FindClass函数获取类的Class引用
  2. 调用GetStaticFieldID函数获取Class引用中某个静态变量ID
  3. 调用GetStaticXXXField(如GetStaticIntField)函数获取静态变量的值,需要传入变量所属Class的引用和变量ID
  4. 调用SetStaticXXXField(SetStaticIntField)函数设置静态变量的值,需要传入变量所属Class的引用、变量ID和变量的值

JNI层访问和修改JAVA实例方法与静态方法

  • 调用静态方法使用CallStaticXXXMethod/V/A函数,XXX代表返回值的数据类型。如:CallStaticIntMethod
void (JNICALL *CallStaticVoidMethod)   (JNIEnv *env, jclass cls, jmethodID methodID, ...);  void (JNICALL *CallStaticVoidMethodV)   (JNIEnv *env, jclass cls, jmethodID methodID, va_list args);  void (JNICALL *CallStaticVoidMethodA)   (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args);  
  • 调用实例方法使用CallXXXMethod/V/A函数,XXX代表返回的数据类型,如:CallIntMethod
void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);void        (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);void        (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
  • 获取一个实例方法的ID,使用GetMethodID函数,传入方法名称和方法签名
    jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
  • 获以一个静态方法的ID,使用GetStaticMethodID函数,传入方法名称和方法签名
    jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
  • 获取构造方法ID,方法名称使用”<init>”,比如获取默认构造方法
(*env)->GetMethodID(env,clazz, "<init>","()V");  
  • 获取一个类的Class实例,使用FindClass函数,传入类描述符。JVM会从classpath目录下开始搜索。
    jclass      (*FindClass)(JNIEnv*, const char*);
  • 创建一个类的实例,使用NewObject函数,传入Class引用和构造方法ID
    jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);    jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);    jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
  • 删除局部变量引用,使用DeleteLocalRef,传入引用变量
    void DeleteLocalRef(jobject localRef)    { functions->DeleteLocalRef(this, localRef); }
  • 方法签名格式:(形参参数列表)返回值类型。注意:形参参数列表之间不需要用空格或其它字符分隔
  • 类描述符格式:L包名路径/类名;,包名之间用/分隔。如:Ljava/lang/String;
  • 调用GetMethodID获取方法ID和调用FindClass获取Class实例后,要做异常判断,判断返回值是否为NULL

更多相关文章

  1. android中使用BitmapFactory的decodeStream()方法解码图片失败问
  2. Android(安卓)BindService
  3. android 通过intent调用短消息的正确方法
  4. Android(安卓)JiaoZiVideoPlayer源码分析
  5. Android(安卓)Gesture
  6. android Binder的使用方式 示例
  7. 例说 android:mimeType
  8. Android(安卓)控制ScrollView滚动的实例详解
  9. Android(安卓)View 绘制过程

随机推荐

  1. C#与Android通过adb实现usb通讯
  2. Android(安卓)和 JS 交互时调用不成功解
  3. android 应用如何获取系统权限 以及root
  4. Android代码混淆只需简单三步
  5. Android(安卓)的系统属性(SystemProperti
  6. Android(安卓)他人面试题总结
  7. Android学习笔记(27):日历视图Calendar
  8. Android(安卓)定时/倒计时工具 - 加强版 C
  9. Android(安卓)opencv(三) 边缘检测Sobel
  10. Android中实现下载和解压zip文件功能代码