JNI学习(二)调用java数据、字符串、数组,对象以及类
来源:互联网 发布:足球视频直播软件 编辑:程序博客网 时间:2024/06/03 19:09
在学习过调用原生函数来返回字符串以后,开始学习在原生方法中调用java中的资源,包括int型数据,string型数据,Array数组,object对象和class类,下面以此介绍。
1、调用int型数据
int型数据是最常用的数据类型之一,所以我从调用int型数据入手学习,非常简单
首先在MainActivity中声明本地方法
public native int intFromJNI();
注意返回值为int型即可,然后在.cpp文件中依照规则,编写本地方法名和方法内容
extern "C"JNIEXPORT jint JNICALLJava_com_seuic_ndkstudy_MainActivity_intFromJNI( JNIEnv *env, jobject this ){ return 1;}
注意返回类型为jint,这是jni层和java中int的对应类型。
最后在MainActivity中使用TextView组件显示返回结果即可
TextView tv1 = (TextView) findViewById(R.id.sample_text); tv1.setText(intFromJNI()+"");
在应用中可以显示返回值为1
2、调用string型数据
同样,先声明本地方法
public native String stringFromJNI(String prompt);
然后编写本地方法
extern "C"JNIEXPORT jstring JNICALLJava_com_seuic_ndkstudy_MainActivity_stringFromJNI( JNIEnv *env, jobject this , jstring prompt){ const char *c_data = env->GetStringUTFChars(prompt,NULL); int len_data = strlen(c_data); char cc_data[len_data]; strcpy(cc_data, c_data); env->ReleaseStringUTFChars(prompt,c_data); return env->NewStringUTF(cc_data);}
这里本地方法的作用是调用java中的字符串prompt,将其复制到本地字符串数组cc_data中,然后释放调用的java字符串资源,最后将cc_data作为字符串返回至java层。首先用GetStringUTFChars(prompt,NULL)将prompt字符串地址传递给c_data;通过strlen()方法获取字符串的长度并保存在len_data中;通过strcpy函数将字符串从c_data中地址位置复制到cc_data字符数组中;通过ReleaseStringUTFChars(prompt,c_data)函数释放调用的资源;最后通过env->NewStringUTF(cc_data)函数生成新数组并返回。
接着在MainActivity中调用TextView组件显示返回的字符串,验证成功
3、调用数组
数组的调用跟字符串调用比较接近,下面进行实现,声明本地方法
private native int sumArray(int[] array,int arrLength);
本地方法程序如下
extern "C"JNIEXPORT jint JNICALLJava_com_seuic_ndkstudy_MainActivity_sumArray( JNIEnv *env, jobject /* this */, jintArray array, jint arrayLength){// jint buf[arrayLength];// env->GetIntArrayRegion(array,0,arrayLength,buf); jint *carr; carr = env->GetIntArrayElements(array,NULL); int length = env->GetArrayLength(array); if(carr == NULL) { return 0; } int sum = 0; for(int i=0 ; i<arrayLength ; i++) {// sum += buf[i]; sum += carr[i]; } env->ReleaseIntArrayElements(array,carr,0); return length;}
在本地方法中,在java调用中即传入了数组长度arrayLength,方便在本地方法中处理数组数据,后来为了更方便使用,在本地方法中使用
int length = env->GetArrayLength(array);
来获取传入的数组长度,也验证可行。
env->GetIntArrayRegion(array,0,arrayLength,buf);
方法将array数组中,从0到arrayLength长度的数据传入buf数组。
在调用结束之后使用
env->ReleaseIntArrayElements(array,carr,0);
来释放占用的资源。
进行求和结束后,返回数组元素之和,在MainActivity中显示,验证成功。
4、调用object对象
调用int型数据,string型字符串,数组都比较简单,下面进行调用对象的习,首先新建一个DataProces类,在此类中声明本地方法
private native int GetJavaData();
对编写本地方法
extern "C"JNIEXPORT jint JNICALLJava_com_seuic_ndkstudy_DataProcess_GetJavaData( JNIEnv *env, jobject obj ){// jclass cls = env->GetObjectClass(obj); jclass cls = env->FindClass("com/seuic/ndkstudy/DataProcess"); if(cls == NULL) return 0; jmethodID jmethodID1 = env->GetMethodID(cls,"DataSum","()V"); env->CallVoidMethod(obj,jmethodID1); return 1;}
本地方法的作用是用过传入的object对象,查找到相应的类,并调用该类中的一个方法。
在DataProcess类中实现如下
public DataProcess(int newData) { this.data1 = newData; GetJavaData(); } public void DataSum() { this.data1 += 1; }
最后在MainActivity中显示,验证成功。
5、调用类
在jni中调用类有几种方式,我验证了两种,第一种通过传入的对象来找到对应的类,另一种通过路径直接找到类。
// jclass cls = env->GetObjectClass(obj); jclass cls = env->FindClass("com/seuic/ndkstudy/DataProcess");
完整代码如下
extern "C"JNIEXPORT jobject JNICALLJava_com_seuic_ndkstudy_MainActivity_GetJavaClass( JNIEnv *env,// jobject object) jclass jclass1){// jclass cls = env->GetObjectClass(obj); jclass cls = env->FindClass("com/seuic/ndkstudy/DataProcess"); if(cls == NULL) return 0; jmethodID jmethodID1 = env->GetMethodID(cls,"DataSum","()V"); jmethodID jmethodID2 = env->GetMethodID(cls,"<init>","(I)V"); jobject obj = env->NewObject(cls,jmethodID2,100); env->CallVoidMethod(obj,jmethodID1); return obj;}
在调用java类之后,然后新建一个类的实例对象,然后返回对象,在MainActivity中声明如下
private native DataProcess GetJavaClass();
因为返回的是DataProcess类的对象,所以此处声明返回值也为DataProcess。验证返回成功,可以显示在jni中新建对象的属性值。
- JNI学习(二)调用java数据、字符串、数组,对象以及类
- JNI学习(四)、本地方法创建java对象,以及对字符串的操作
- JNI学习笔记(二)--C++传递结构体、String、数组对象给Java
- JNI学习笔记(二)--C++传递结构体、String、数组对象给Java
- Java JNI学习(二)
- JNI之c调用java的函数,调用java的构造生成对象,得到java的成员,以及C返回Java字符串乱码
- Java调用本地接口(JNI) (二)
- [JNI]学习笔记系列:二 基本数据类型,字符串,数据
- JNI入门二:字符串和字符串数组
- JNI学习(一)(c和java层对象互相调用)
- JAVA->JNI 传递字符串数组
- java学习笔记5.22多维数组以及对象和类
- java学习(3)-数组以及面向对象
- Android JNI学习笔记(四)-数据类型映射以及native调用java
- Java SE学习(二)数组与字符串、数据类型转
- JNI学习之---用jni API 访问java对象的属性,方法,调用构造器。
- JNI学习笔记:(1)开篇(2)本地代码访问Java代码 (3)本地方法取得Java属性/调用java方法 (4)本地代码创建Java对象(包括javaString) (5) 本地方法处理java数组
- Android-java调用本地方法返回字符串显示在界面上/NDK-JNI开发实例(二)
- AVPlayer的使用
- 有符号数与无符号数的加减法
- Oracle运行mybatis动态sql会抛一个异常
- mybatis中#{}与${}的差别(如何防止sql注入)
- 【Centos7】YUM Repository安装MySQL
- JNI学习(二)调用java数据、字符串、数组,对象以及类
- 大型网站架构系列:缓存在分布式系统中的应用(三)
- leveldb——leveldb入门篇之Linux下编译配置和使用
- spring实现读写分离
- SNMP协议详解
- 在DataSet中添加DataTable
- 最详细的Log4j使用教程
- mysql查询结果导出文件 excel 或者csv
- 新路程------windows虚拟机用cutecom注意事项