一、jni简介
java native interface的简称,
二、创建带native(c++)环境的Android工程
2.2、jni接口文件分析
创建好工程后,会默认生成一个jni接口文件,一般命名为:main/cpp/native-lib.cpp
cpp
/**
* extern "C" :表示下面的代码,采用c的编译方式,具体原因在于JNIEnv是由c语言实现
* JNIEXPORT :JNI重要标记关键字(标记为该方法可以被外部调用)
* jstring :jni方法的返回值
* JNICALL : 关键字(可以缺省),作用(约束函数入栈顺序,和堆栈内存清理的规则)
* 方法名:Java_com_zhoumohan_learnjni_MainActivity_stringFromJNI,生成规则为:Java_ + 包名 + 类名 + 方法名,
* 中间用下划线连接,若包名、类名、方法名中有_,则会生成为_1,表示这个下划线是包名、类名、方法名中的下划线。
* 这种方式属于静态注册,通过有规则的方法名和java文件中的方法进行关联
*
* JNIEnv :可以说是JNI中最重要的部分,它是一个结构体,内部定义了所有的jni操作的函数,它被定义在jni.h中
*/
extern "C" JNIEXPORT jstring JNICALL
Java_com_zhoumohan_learnjni_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
//如果当前是 native-lib.c
//(*env)->xxx函数
//(*env)->DeleteLocalRef()
//c语言是 JNIEnv *env 二级指针
//(*env)->DeleteLocalRef(env,NULL); c是没有面向对象的,想持有env环境,就必须传递进去
//如果当前是 native-lib.cpp
//env->xxx函数
//env->DeleteLocalRef()
//c++语言是 JNIEnv *env 一级指针
//env->DeleteLocalRef(env,NULL); c++是有面向对象的,本来就持有this,就不必传递进去
// 默认采用c++的方式
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
三、jni基础
3.1、jni数据类型及签名对应关系
Java数据类型 | JNI数据类型 | C/C++数据类型 | 签名 |
---|---|---|---|
boolean | jboolean | unsigned char | Z |
byte | jbyte | signed char | B |
char | jchar | unsigned short | C |
short | jshort | short | S |
int | jint | int | I |
long | jlong | long long | J |
float | jfloat | float | F |
double | jdouble | double | D |
void | void | void | V |
对象 | jobject | 对象 | L+全限定名+; |
*例:如String, Ljava/lang/String;
但如果我记不住或不确定该怎么办呢?可以通过java工具来查看:
构建工程后,进入此目录:build\intermediates\javac\debug\classes,这里有所有编译完生成的.class文件,通过javap命令可以看到对应的签名信息:
cpp
javap -s -p .\com\demo\learnjni\MainActivity.class
3.2、JNIENV 中的函数使用方法
看似JNIENV中的函数有很多,实则多数都有规律可循,我认为具体可分为以下几类:
1.基础函数,即这些函数为其他函数能调用的基本条件
函数 | 描述 |
---|---|
jclass FindClass(const char* name) | 通过全类名(java)获取对应的jclass对象 |
jclass GetObjectClass(jobject obj) | 通过具体对象获取对应的class对象 |
jclass GetSuperclass(jclass clazz) | 获取传入clazz的父类的jclass对象 |
jfieldId GetFieldID( jclass clazz, //所属的类 const char* name, //属性名 const char* sig) //属性的签名 | 获取类成员属性的Id |
jfieldId GetStaticFieldID( jclass clazz, //所属的类 const char* name, //属性名 const char* sig) //属性的签名 | 获取类静态成员属性的Id |
jmethodId GetMethodID( jclass clazz, //方法所属的类 const char* name, //方法名 const char* sig) //方法签名 | 获取类方法的Id |
jmethodId GetStaticMethodID( jclass clazz, //方法所属的类 const char* name, //方法名 const char* sig) //方法签名 | 获取类静态方法的Id |
2.获取类(对象)成员属性的值
函数 | 描述 |
---|---|
jobject GetObjectField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jboolean GetBooleanField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jbyte GetByteField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jchar GetCharField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jshort GetShortField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jint GetIntField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jlong GetLongField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jfloat GetFloatField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jdouble GetDoubleField(jobject obj, jfieldID fieldID) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
3.设置类(对象)成员属性的值
函数 | 描述 |
---|---|
void SetObjectField(jobject obj, jfieldID fieldID,jobject value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetBooleanField(jobject obj, jfieldID fieldID,jboolean value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetByteField(jobject obj, jfieldID fieldID,jbyte value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetCharField(jobject obj, jfieldID fieldID,jchar value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetShortField(jobject obj, jfieldID fieldID,jshort value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetIntField(jobject obj, jfieldID fieldID,jint value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetLongField(jobject obj, jfieldID fieldID,jlong value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetFloatField(jobject obj, jfieldID fieldID,jfloat value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
void SetDoubleField(jobject obj, jfieldID fieldID,jdouble value) | 参数: jobject obj :对象 jfieldID fielD:通过GetFieldID()获取到的 类成员属性的id。 value:对应类型的值 描述: 设置某个对象的某个成员属性的值。 |
4.获取类静态成员属性的值
函数 | 描述 |
---|---|
jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jchar GetStaticCharField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jshort GetStaticShortField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jint GetStaticIntField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jlong GetStaticLongField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类成员属性的id。 描述: 获取某个对象的某个成员属性的值。 (除jni.h中定义的类型外,所有对象用jobject类型接收) |
5.设置类静态成员的值
函数 | 描述 |
---|---|
void SetStaticObjectField(jclass clazz, jfieldID fieldID,jobject value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticBooleanField(jclass clazz, jfieldID fieldID,jboolean value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticByteField(jclass clazz, jfieldID fieldID,jbyte value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticCharField(jclass clazz, jfieldID fieldID,jchar value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticShortField(jclass clazz, jfieldID fieldID,jshort value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticIntField(jclass clazz, jfieldID fieldID,jint value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetstaticLongField(jclass clazz, jfieldID fieldID,jlong value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticFloatField(jclass clazz, jfieldID fieldID,jfloat value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
void SetStaticDoubleField(jclass clazz, jfieldID fieldID,jdouble value) | 参数: jclass clazz :静态成员所属的类的jclass对象 jfieldID fielD:通过GetStaticFieldID()获取到的 类静态成员属性的id。 value:对应类型的值 描述: 设置某个类的某个静态成员属性的值。 |
6.字符串操作相关
函数 | 描述 |
---|---|
jstring NewString(const jchar* unicodeChars, jsize len) | 描述:通过jchar*创建jstring 参数:jchar* 数组 jsize len :jchar* 数组的长度 |
jsize GetStringLength(jstring string) | 获取jstring的长度 |
const jchar* GetStringChars(jstring string, jboolean* isCopy) | jstring转jchar*,isCopy一般都为false(NULL)即可 |
void ReleaseStringChars(jstring string, const jchar* chars) | 释放回收内存空间操作 |
jstring NewStringUTF(const char* bytes) | c字符串转jstring,一般用于由c层向java层传递字符串 |
jsize GetStringUTFLength(jstring string) | 获取jstring的长度(utf编码格式) |
const char* GetStringUTFChars(jstring string, jboolean* isCopy) | jstring转c层字符串,一般用于c层接收java层传入的字符串,isCopy一般都为false(NULL)即可 |
void ReleaseStringUTFChars(jstring string, const char* utf) | 与上一个函数相对应,用完char*后,释放回收内存 |
7.数组相关
692 ~ 735,786~825,828~850