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

一、jni简介

java native interface的简称,

官方文档

二、创建带native(c++)环境的Android工程

2.2、jni接口文件分析

创建好工程后,会默认生成一个jni接口文件,一般命名为:main/cpp/native-lib.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命令可以看到对应的签名信息:

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)
jbyte GetByteField(jobject obj, jfieldID fieldID)
jchar GetCharField(jobject obj, jfieldID fieldID)
jshort GetShortField(jobject obj, jfieldID fieldID)
jint GetIntField(jobject obj, jfieldID fieldID)
jlong GetLongField(jobject obj, jfieldID fieldID)
jfloat GetFloatField(jobject obj, jfieldID fieldID)
jdouble GetDoubleField(jobject obj, jfieldID fieldID)

3.设置类(对象)成员属性的值

函数 描述
void SetObjectField(jobject obj, jfieldID fieldID,jobject value)

参数:

jobject obj :对象

jfieldID fielD:通过GetFieldID()获取到的

类成员属性的id。

value:对应类型的值

描述:

设置某个对象的某个成员属性的值。

void SetBooleanField(jobject obj, jfieldID fieldID,jboolean value)
void SetByteField(jobject obj, jfieldID fieldID,jbyte value)
void SetCharField(jobject obj, jfieldID fieldID,jchar value)
void SetShortField(jobject obj, jfieldID fieldID,jshort value)
void SetIntField(jobject obj, jfieldID fieldID,jint value)
void SetLongField(jobject obj, jfieldID fieldID,jlong value)
void SetFloatField(jobject obj, jfieldID fieldID,jfloat value)
void SetDoubleField(jobject obj, jfieldID fieldID,jdouble value)

4.获取类静态成员属性的值

函数 描述
jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)

参数:

jclass clazz :静态成员所属的类的jclass对象

jfieldID fielD:通过GetStaticFieldID()获取到的

类成员属性的id。

描述:

获取某个对象的某个成员属性的值。

(除jni.h中定义的类型外,所有对象用jobject类型接收)

jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
jint GetStaticIntField(jclass clazz, jfieldID fieldID)
jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)

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)
void SetStaticByteField(jclass clazz, jfieldID fieldID,jbyte value)
void SetStaticCharField(jclass clazz, jfieldID fieldID,jchar value)
void SetStaticShortField(jclass clazz, jfieldID fieldID,jshort value)
void SetStaticIntField(jclass clazz, jfieldID fieldID,jint value)
void SetstaticLongField(jclass clazz, jfieldID fieldID,jlong value)
void SetStaticFloatField(jclass clazz, jfieldID fieldID,jfloat value)
void SetStaticDoubleField(jclass clazz, jfieldID fieldID,jdouble 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.数组相关

8.

692 ~ 735,786~825,828~850

你可能感兴趣的:(android)