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

相关推荐
Dingdangr3 小时前
Android中的Intent的作用
android
技术无疆3 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
GEEKVIP3 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
Jouzzy10 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb
极客先躯11 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
Good_tea_h13 小时前
Android中的单例模式
android·单例模式
计算机源码社18 小时前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
丶白泽18 小时前
重修设计模式-结构型-门面模式
android
晨春计20 小时前
【git】
android·linux·git
标标大人21 小时前
c语言中的局部跳转以及全局跳转
android·c语言·开发语言