Android NDK 开发学习笔记(一) --jni

一、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

相关推荐
闲暇部落2 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX4 小时前
Android 分区相关介绍
android
大白要努力!5 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee5 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood5 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-8 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen11 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年18 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿20 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神21 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri