JNI之函数介绍四之数组操作

NDK  2023年7月25日 pm6:55发布1年前 (2023)更新 城堡大人
85 0 0

前言

今天介绍一下JNI数组相关操作函数。

正文

GetArrayLength

# env: JNI 接口指针
# array: Java 数组对象
jsize GetArrayLength(JNIEnv *env, jarray array);

返回数组中的元素数(数组的长度)。

NewObjectArray

# env: JNI 接口指针
# length:数组大小
# elementClass:数组元素类
# initialElement:初始值
jarray NewObjectArray(JNIEnv *env, jsize length,jclass elementClass, jobject initialElement);

构造新的数组,保存类 elementClass 中的对象,所有元素初始值均设为initialElement 。

# 创建一个Person数组,每个元素为NULL
jobjectArray array = env->NewObjectArray(length, clazz_Person, NULL);

没怎么用过~_~

如果成功,返回数组对象,否则返回NULL。

GetObjectArrayElement

# env: JNI 接口指针
# array: Java 数组
# index:数组下标
jobject GetObjectArrayElement(JNIEnv *env,jobjectArray array, jsize index);

返回 Object 数组的元素。

如果 index 不是数组中的有效下标,抛出异常ArrayIndexOutOfBoundsException。

SetObjectArrayElement

# env: JNI 接口指针
# array: Java 数组
# index:数组下标
# value:新值
void SetObjectArrayElement(JNIEnv *env, jobjectArray array,jsize index, jobject value);

设置 Object 数组的元素。

如果 index 不是数组中的有效下标,抛出ArrayIndexOutOfBoundsException。

如果 value 的类不是数组元素类的子类,抛出ArrayStoreException。

New<PrimitiveType>Array

# env: JNI 接口指针
# length:数组长度
ArrayType New<PrimitiveType>Array(JNIEnv *env, jsize length);

创建对应<PrimitiveType>类型的数组。

NewBooleanArray()   jbooleanArray
NewByteArray()      jbyteArray
NewCharArray()      jcharArray
NewShortArray()     jshortArray
NewIntArray()       jintArray
NewLongArray()      jlongArray
NewFloatArray()     jfloatArray
NewDoubleArray()    jdoubleArray
NewIntArray

以int类型为例

jintArray NewIntArray(JNIEnv *env, jsize length);

Get<PrimitiveType>ArrayElements

# env: JNI 接口指针
# array: Java 字符串对象
# isCopy:指向布尔值的指针
NativeType *Get<PrimitiveType>ArrayElements(JNIEnv *env,ArrayType array, jboolean *isCopy);

一组返回基本类型数组体的函数。结果在调用相应的Release<PrimitiveType>ArrayElements() 函数前将一直有效。 由于返回的数组可能是 Java 数组的副本, 因此对返回数组的更改不必在基本类型数组中反映出来,直到调用了 Release<PrimitiveType>ArrayElements()。

如果 isCopy 不是 NULL, *isCopy 在复制完成后即被设为 JNI_TRUE。 如果未复制,则设为 JNI_FALSE。

注意事项:

  1. Get<PrimitiveType>ArrayElements 替换为表中某个实际的基本类型 元素访问器例程名

  2. 将 ArrayType 替换为对应的数组类型。

  3. 将 NativeType 替换为该例程对应的本地类型。

GetIntArrayElements

以int类为例

jint * GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy);

Release<PrimitiveType>ArrayElements

# env: JNI 接口指针
# array: Java 数组对象
# elems:指向数组元素的指针
# mode:释放模式
void Release<PrimitiveType>ArrayElements(JNIEnv *env,ArrayType array, NativeType *elems, jint mode);

通知虚拟机平台相关代码无需再访问 elems 的一组函数。 elems 参数是一个通过使用对应的 Get<PrimitiveType>ArrayElements() 函数由 array 导出的指针。必要时,该函数将把对 elems 的修改复制回基本类型数组。

mode 参数将提供有关如何释放数组缓冲区的信息。如果 elems 不是 array 中数组元素的副本, mode 将无效。否则, mode 将具有下表所述的功能:

  1. 0 复制回内容并释放 elems 缓冲区

  2. JNI_COMMIT 复制回内容但不释放 elems 缓冲区

  3. JNI_ABORT 释放缓冲区但不复制回变化

多数情况下,编程人员将把“ 0” 传给 mode 参数以确保固定的数组和复制的数组保持一致。 其它选项可以使编程人员进一步控制内存管理, 但使用时务必慎重。

ReleaseIntArrayElements

以int类为例

void ReleaseIntArrayElements(JNIEnv *env,jintArray array, jint *elems, jint mode);

Set<PrimitiveType>ArrayRegion

# env: JNI 接口指针
# array: Java 数组
# start:起始下标
# len:要复制的元素数
# buf:源缓冲区
void Set<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, NativeType *buf);

将基本类型数组的某一区域从缓冲区中复制回来的一组函数。

如果区域中的某个下标无效,就抛出ArrayIndexOutOfBoundsException

Get<PrimitiveType>ArrayRegion

# env: JNI 接口指针
# array: Java 指针
# start:起始下标
# len:要复制的元素数
# buf:目的缓冲区
void Get<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, NativeType *buf);

将基本类型数组某一区域复制到缓冲区中的一组函数。

如果区域中的某个下标无效,抛出ArrayIndexOutOfBoundsException。

参考文章

  1. JNI完全手册]》

  2. NDK中jni.h头文件完整内容

  3. JNI引用类型数组操作

 历史上的今天

  1. 2022: Android进程间通信方式Messenger的简单记录(0条评论)
  2. 2021: 余光中:绝色(0条评论)
  3. 2019: 龙应台:中国人,你为什么不生气?(0条评论)
  4. 2018: Launcher2之拖拽事件(0条评论)
版权声明 1、 本站名称: 笔友城堡
2、 本站网址: https://www.biumall.com/
3、 本站部分文章来源于网络,仅供学习与参考,如有侵权,请留言

暂无评论

暂无评论...

随机推荐

Android String占位格式化

前言记录一下Android中String的占位。其实就是让指定内容固定占用多少个位置,主要是为了美化显示。简单记录一下,方便自己查阅。正文比如,下面打印是不够美观的[1][100]下面是比较好看的(美化后)[ 1][100]或[001][100]这样就占的宽度一样,看起...

addr2line.exe的简单使用

前言不常用,偶尔需要,在学习JNI时也学习addr2line工具的使用,记录于此,方便自己查阅。正文addr2line工具在Android NDK包中,我这里以Window版的为例。我这下载的是android-ndk-r21d-windows-x86_64.zip解压和环境配置我这不解...

Android中获得 LayoutInflater 实例的三种方式

以下文章对LayoutInflater总结的不错,摘抄于此,部分内容稍微改动。在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而f...

bat脚本命令简介

批处理,也称为批处理脚本,英文译为BATCH,批处理文件后缀BAT就取的前三个字母。它的构成没有固定格式,只要遵守以下这条就ok了:每一行可视为一个命令,每个命令里可以含多条子命令,从第一行开始执行,直到最后一行结束,它运行的平台是DOS。批处理有一个很鲜明的特点:使用方便、灵活,功能强大,自动化程...

Android在线源码查看

前言记录一下在线看源码的几个地方,方便自己查阅。本文摘抄的。正文aospxref网址:http://aospxref.com/优点:更新速度快缺点:历史版本较少androidxref网址:http://androidxref.com/优点:历史版本较多缺...

git diff提示filemode发生改变

在使用git的时候遇到的,因此摘抄于此。今天clone代码,git status显示修改了大量文件,git diff提示filemode变化,如下:diff --git a/Android.mk b/Android.mkold mode 100644new mode 100755原...