ndk

NDK学习笔记(二)

Posted by alonealice on 2016-12-26

之前的文章中我详细的介绍了第一个NDK程序,后面要讲讲如何使用jni的接口,实现更多的功能。

jstring相关方法

首先要讲讲jstring相关方法。

NewStringUTF

NewStringUTF函数传入一个字符串,返回jstring对象。

1
2
3
4
5
6
7
8
9
10
char p[20]="hello";
return env->NewStringUTF(p);
或者
char *p="hello";
return env->NewStringUTF(p);
或者
std::string hello = "hello";
return env->NewStringUTF(hello.c_str());
或者
return env->NewStringUTF("hello");

以上4中方式在java层中返回的都是hello。

GetStringLength和GetStringUTFLength

GetStringLength函数顾名思义就是获取jstring的长度,它需要传入一个jstring对象,返回jstring的长度。

1
2
3
4
5
std::string hello="123456";
jstring s=env->NewStringUTF(hello.c_str());
return env->GetStringLength(s);
//或
return env->GetStringUTFLength(s);

两个方法的区别是GetStringUTFLength获取jstring的UTF-8编码字符串的长度,而GetStringLength函数是获取Unicode编码的jstring字符串长度。这里的jstring既可以通过内部创建,也可以通过外部java层传入进来,最后java层可以获取到6。

GetStringChars和ReleaseStringChars

GetStringChars函数能将jstring对象转为16位的jchar,而则能将内存释放。

1
2
3
jstring s=env->NewStringUTF(str);  //创建jstring对象
const jchar *p=env->GetStringChars(s,NULL); //将jstring转为16位jchar
env->ReleaseStringChars(s,p);//释放内存

GetStringUTFChars和ReleaseStringUTFChars

ReleaseStringUTFChars则是将jstring数据转为字符串,而ReleaseStringUTFChars同样是是否内存

1
2
3
jstring s=env->NewStringUTF("hello");
const char *p=env->GetStringUTFChars(s,NULL);
env->ReleaseStringUTFChars(s,p);

最后字符串p的值就是hello

GetStringUTFRegion和GetStringRegion

这对函数会把源字符串复制到一个预先分配的缓冲区内,然后会获取Unicode和UTF-8编码字符串指定范围内的内容。

1
2
3
4
5
jstring s=env->NewStringUTF("hello");
char p[30]="123";
char *t=p+3;
env->GetStringUTFRegion(s,0,3,t);
return env->NewStringUTF(p);

这里有几点需要注意一下:首先它需要有一个预先分类号的缓冲区,所以需要先定义一个字符串内存区域,同时把指针指过去,然后在进行赋值,同时,如果这个函数还会做jstring越界检查,如果检查发现越界了,会抛出StringIndexOutOfBoundsException异常。而且由于它不会进行内存分配,所以不需要回收内存。

Array相关方法

NewTypeArray

创建固定容量的array数组,如NewIntArray,NewLongArray等。

1
2
jintArray array=env->NewIntArray(3);
return array;

java层能够获取到一个容量为3的int数组。

GetArrayLength

获取array的长度

1
2
jintArray array=env->NewIntArray(3);
return env->GetArrayLength(array);

java层获取到长度3

GetTypeArrayElements

将jTypeArray转化为jType *,从而可以操作里面的值。

1
2
3
4
5
6
7
8
9
jint *as=env->GetIntArrayElements(array,NULL);
as[0]=20;
return as[0];


java层:
public static int[] intarray={10,4,54};
JavaHelper.createArray(JavaHelper.intarray);
最后java层获取到的值为20

GetPrimitiveTypeArrayRegion

将部分typearray数据复制到type数组

1
2
3
4
5
6
7
8
9
jint nativeArray[3];
env->GetIntArrayRegion(array,0,3,nativeArray);
for(int i=0;i<3;i++){
nativeArray[i]+=9;
}
return nativeArray[0];

java层传入{1,2,3}
返回10

SetTypeArrayRegion

将type数组转化为jtypeArray

1
2
3
4
5
6
7
8
9
jint nativeArray[3];
env->GetIntArrayRegion(array,0,3,nativeArray);
for(int i=0;i<3;i++){
nativeArray[i]+=9;
}
env->SetIntArrayRegion(array,0,3,nativeArray);
return array;

java层输入{1,2,3,4,5},返回{10,11,12,4,5}