Android NDK开发入门,android组件化架构

| long | jlong | 有符号 | 64字节 |

| float | jfloat | 有符号 | 32字节 |

| double | jdouble | 有符号 | 64字节 |

对应的引用类型如下表所示。

| Java 类型 | Native类型 |

| — | — |

| java.lang.Class | jclass |

| java.lang.Throwable | jthrowable |

| java.lang.String | jstring |

| jjava.lang.Object[] | jobjectArray |

| Byte[] | jbyteArray |

| Char[] | jcharArray |

| Short[] | jshortArray |

| int[] | jintArray |

| long[] | jlongArray |

| float[] | jfloatArray |

| double[] | jdoubleArray |

ni233/article/details/109277713)3.1基本数据类型

Native的基本数据类型其实就是将C/C++中的基本类型用typedef重新定义了一个新的名字,在JNI中可以直接访问,如下所示。

typedef uint8_t jboolean; /* unsigned 8 bits */

typedef int8_t jbyte; /* signed 8 bits */

typedef uint16_t jchar; /* unsigned 16 bits */

typedef int16_t jshort; /* signed 16 bits */

typedef int32_t jint; /* signed 32 bits */

typedef int64_t jlong; /* signed 64 bits */

typedef float jfloat; /* 32-bit IEEE 754 */

typedef double jdouble; /* 64-bit IEEE 754 */

3.2 引用数据类型

如果使用C++语言编写,则所有引用派生自jobject根类,如下所示。

class _jobject {};

class _jclass : public _jobject {};

class _jstring : public _jobject {};

class _jarray : public _jobject {};

class _jobjectArray : public _jarray {};

class _jbooleanArray : public _jarray {};

class _jbyteArray : public _jarray {};

class _jcharArray : public _jarray {};

class _jshortArray : public _jarray {};

class _jintArray : public _jarray {};

class _jlongArray : public _jarray {};

class _jfloatArray : public _jarray {};

class _jdoubleArray : public _jarray {};

class _jthrowable : public _jobject {};

JNI使用C语言时,所有引用类型都使用jobject。

4,JNI的字符串处理

4.1 native操作JVM

JNI会把Java中所有对象当做一个C指针传递到本地方法中,这个指针指向JVM内部数据结构,而内部的数据结构在内存中的存储方式是不可见的.只能从JNIEnv指针指向的函数表中选择合适的JNI函数来操作JVM中的数据结构。

比如native访问java.lang.String 对应的JNI类型jstring时,不能像访问基本数据类型那样使用,因为它是一个Java的引用类型,所以在本地代码中只能通过类似GetStringUTFChars这样的JNI函数来访问字符串的内容。

4.2 字符串操作的示例

//调用

String result = operateString(“待操作的字符串”);

Log.d(“xfhy”, result);

//定义

public native String operateString(String str);

然后在C中进行实现,代码如下。

extern “C”

JNIEXPORT jstring JNICALL

Java_com_xfhy_jnifirst_MainActivity_operateString(JNIEnv *env, jobject thiz, jstring str) {

//从java的内存中把字符串拷贝出来 在native使用

const char *strFromJava = (char *) env->GetStringUTFChars(str, NULL);

if (strFromJava == NULL) {

//必须空检查

return NULL;

}

//将strFromJava拷贝到buff中,待会儿好拿去生成字符串

char buff[128] = {0};

strcpy(buff, strFromJava);

strcat(buff, " 在字符串后面加点东西");

//释放资源

env->ReleaseStringUTFChars(str, strFromJava);

//自动转为Unicode

return env->NewStringUTF(buff);

}

4.2.1 native中获取JVM字符串

在上面的代码中,operateString函数接收一个jstring类型的参数str,jstring是指向JVM内部的一个字符串,不能直接使用。首先,需要将jstring转为C风格的字符串类型char*后才能使用,这里必须使用合适的JNI函数来访问JVM内部的字符串数据结构。

GetStringUTFChars(jstring string, jboolean* isCopy)对应的参数的含义如下:

  • string : jstring,Java传递给native代码的字符串指针。

  • isCopy : 一般情况下传NULL,取值可以是JNI_TRUE和JNI_FALSE,如果是JNI_TRUE则会返回JVM内部源字符串的一份拷贝,并为新产生的字符串分配内存空间。如果是JNI_FALSE则返回JVM内部源字符串的指针,意味着可以在native层修改源字符串,但是不推荐修改,因为Java字符串的原则是不能修改的。

Java中默认是使用Unicode编码,C/C++默认使用UTF编码,所以在native层与java层进行字符串交流的时候需要进行编码转换。GetStringUTFChars就刚好可以把jstring指针(指向JVM内部的Unicode字符序列)的字符串转换成一个UTF-8格式的C字符串。

4.2.2 异常处理

在使用GetStringUTFChars的时候,返回的值可能为NULL,这时需要处理一下,

你可能感兴趣的:(程序员,架构,移动开发,android)