1、声明native方法

public class ComplexObject {

	/**
* 返回一个对象数组
* @param val
* @return
*/
public native Person[] receiverBeanArray(String val); /**
* 获取对象
* @return
*/
public native Person getPerson(); /**
* 获取对象的集合
* @return
*/
public native ArrayList<Person> getPersonList(); }

2、Person类对象

有两个构造函数,主要是为了在jni中通过不同的构造函数来创建Person对象。

public class Person {

	public String name;
private int age; public Person() {
super();
} public Person(int age, String name) {
super();
this.age = age;
this.name = name;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
} }

3、jni操作实现

JNI中,构造函数可以和实例方法一样被调用,调用方式也相似。传入“<init>”作为方法名,“V”作为返回类型。你可以通过向JNI函数NewObject传入方法来调用构造函数。

/**
* 拼接字符串
*/
char* strJoin(char *s1, char *s2) {
char *result = malloc(strlen(s1) + strlen(s2) + 1);
if (result == NULL)
exit(1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
/**
* 返回一个数组类型到Java
*/
JNIEXPORT jobjectArray JNICALL Java_com_example_jniandroid_service_ComplexObject_receiverBeanArray
(JNIEnv * env, jobject obj , jstring string) {
jclass objClass = (*env)->FindClass(env, "java/lang/Object");
jobjectArray mails = (*env)->NewObjectArray(env, (jsize) ARRAY_LENGTH,objClass, 0);
jclass personClass = (*env)->FindClass(env,"com/example/jniandroid/bean/Person"); jfieldID field_name = (*env)->GetFieldID(env, personClass, "name","Ljava/lang/String;");
jmethodID construction_id = (*env)->GetMethodID(env, personClass, "<init>","()V");
jfieldID field_age = (*env)->GetFieldID(env,personClass, "age", "I");
jclass mPerson = (*env)->NewObject(env, personClass, construction_id); int i = 0;
//将jstring类型转成char*
char* nameStr = (char*)(*env)->GetStringUTFChars(env,string, 0);
//拼接字符串
const char* name = strJoin(nameStr,"-join jni");
LOGD("数组总和 =%s", name);
for (; i < ARRAY_LENGTH; i++) {
int age = 20+i;
//将Java的字符串和c的字符串进行拼接后赋值给name属性
(*env)->SetObjectField(env, mPerson, field_name, (*env)->NewStringUTF(env,name));
(*env)->SetIntField(env,mPerson, field_age,age);
(*env)->SetObjectArrayElement(env, mails, (jsize)i, mPerson);
}
return mails;
} /**
* 在jni中给Java对象设置值并返回
*/
JNIEXPORT jobject JNICALL Java_com_example_jniandroid_service_ComplexObject_getPerson
(JNIEnv * env, jclass obj) {
//找到Person类
jclass m_cls = (*env)->FindClass(env,"com/example/jniandroid/bean/Person");
//无参数的构造方法
jmethodID m_mid = (*env)->GetMethodID(env,m_cls, "<init>", "()V");
//获取Java中复杂类型以L开始;结尾,中间是类型将.改成/
jfieldID m_fid_name = (*env)->GetFieldID(env,m_cls, "name", "Ljava/lang/String;");
//基本类型,I表示Java中的int
jfieldID m_fid_age = (*env)->GetFieldID(env,m_cls, "age", "I"); if(m_fid_name==NULL){
printf("m_fid_name is null ");
return;
}
if(m_fid_age==NULL){
printf("m_fid_age is null ");
return;
} jobject m_obj = (*env)->NewObject(env,m_cls, m_mid); (*env)->SetObjectField(env,m_obj, m_fid_name, (*env)->NewStringUTF(env,"Set the name Person object in the JNI value"));
(*env)->SetIntField(env,m_obj, m_fid_age,96); return m_obj;
} /**
* 返回ArrayList集合
*/
JNIEXPORT jobject JNICALL Java_com_example_jniandroid_service_ComplexObject_getPersonList(
JNIEnv * env, jobject obj) {
jclass list_cls = (*env)->FindClass(env, "java/util/ArrayList"); //获得ArrayList类引用 jmethodID list_costruct = (*env)->GetMethodID(env, list_cls, "<init>","()V"); //获得得构造函数Id
jobject list_obj = (*env)->NewObject(env, list_cls, list_costruct); //创建一个Arraylist集合对象
//Arraylist类中的 add()方法ID,其方法原型为: boolean add(Object object) ,boolean类型对应的是Z;
jmethodID list_add = (*env)->GetMethodID(env, list_cls, "add","(Ljava/lang/Object;)Z"); jclass personClass = (*env)->FindClass(env,"com/example/jniandroid/bean/Person"); //获得Person类引用
//获得该类型的构造函数 函数名为 <init> 返回类型必须为 void 即 V
jmethodID person_costruct = (*env)->GetMethodID(env, personClass, "<init>","(ILjava/lang/String;)V");
int i=0;
for (; i < 5; i++) {
jstring str = (*env)->NewStringUTF(env, "jni Native");
//通过调用该对象的构造函数来new 一个 Student实例
jobject person_obj = (*env)->NewObject(env, personClass,person_costruct, i, str); //构造一个对象
//执行Arraylist类实例的add方法,添加一个Person对象
(*env)->CallBooleanMethod(env,list_obj, list_add, person_obj);
}
return list_obj;
}

JNI由浅入深_6_简单对象的应用的更多相关文章

  1. JNI由浅入深_10_JNI 综合开发

    1.使用ndk-build时如果找不到某个类,可以使用下面两种方法解决: 1.1 进入src目录 D:\project3\JNIAndroid\src>set classpath=D:\proj ...

  2. JNI由浅入深_9_JNI 异常处理

    1 .本地代码中如何缓存和抛出异常 下面的代码中演示了如何声明一个会抛出异常的本地方法.CatchThrow这个类声明了一个会抛出IllegalArgumentException异常的名叫doit的本 ...

  3. JNI由浅入深_8_JNI缓存字段和方法ID

    获取字段ID和方法ID时,需要用字段.方法的名字和描述符进行一个检索.检索过程相对比较费时,因此本节讨论用缓存技术来减少这个过程带来的消耗.缓存字段ID和方法ID的方法主要有两种.两种区别主要在于缓存 ...

  4. JNI由浅入深_7_c调用Java方法一

    1.在Java中声明方法 <span style="font-size:14px;">/** * javah -encoding utf-8 -jni com.exam ...

  5. JNI由浅入深_5_基本类型应用

    1.基本类型应用 对于JNI处理基本类型还是比较简单的,下面是Java代码: <span style="font-size:14px;"> public native ...

  6. JNI由浅入深_4_JNI基础知识详解

    Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 ...

  7. JNI由浅入深_3_Hello World

    1.需要准备的工具,eclipse,cdt(c++)插件,cygwin(unix)和 android ndk. 在cygwin的etc目录下将ndk的路径引入到profile文件中,可以在cygwin ...

  8. JNI由浅入深_2_C语言基础

    *含义 1.乘法 3*5 2.定义指针变量 int * p://定义了一个名字叫p的变量,能够存放int数据类型的地址 3.指针运算符, //如果p是一个已经定义好的指针变量则*p表示以p的内容为地址 ...

  9. Java JNI 编程进阶 实例+c++数据类型与jni数据类型转换

    原文:http://www.iteye.com/topic/295776 JNI一直以来都很少去关注,但却是我心中的一个结,最近这几天刚好手头有点时间,因此抽空看了一下这方面的东西,整理了一份文档,J ...

随机推荐

  1. 在IIS中部署好WCF服务站点后,本机访问服务无问题,局域网中其他电脑访问不到

    1.问题描述 在IIS中部署好WCF服务站点后,本机访问服务无问题,局域网中其他电脑访问不到. 2.解决方法 (1)控制面板 -> Windows防火墙 -> 高级设置 (2)属性 (3) ...

  2. 文件下载(Servlet/Struts2)

    文件上传(Servlet/Struts2/SpringMVC)的链接:http://www.cnblogs.com/ghq120/p/8312944.html 文件下载 Servlet实现 目录结构 ...

  3. ORACLE-DataGuard-重启服务器的方法

    DG原理:主机向备机传送日志文件,备机执行日志文件,借此与主机数据同步. 依此原理,不难推导出DG的开关机顺序 关机顺序  先主机再备机,这样日志就不会断了 开机顺序 先备机再主机 ,这样的目标也是日 ...

  4. Node.js如何找npm模板

    首先需要去官网下载npm文件 https://www.npmjs.com/ 下载完成,使用CD查看是否安装完成 然后就是贴代码看npm模板的功能 var _ = require('underscore ...

  5. "Error: ANDROID_HOME is not set and "android" command not in your PATH. You must fulfill at least one of these conditions.".

    设置环境变量 set ANDROID_HOME=C:\\android-sdk-windows set PATH=%PATH%;%ANDROID_HOME%\tools;%ANDROID_HOME%\ ...

  6. Web服务器学习总结(一):web服务器简介

    一.WEB服务器 1.1.WEB服务器简介 1.Web服务器是指驻留于因特网上某种类型计算机的程序,是可以向发出请求的浏览器提供文档的程序.当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处 ...

  7. CSS属性之relative

    0.相对定位relative特点 相对定位relative元素总是会占据位置,所占据的位置是在relative元素没有设置left/top/right/bottom属性时的位置: 相对定位relati ...

  8. Vue组件通讯

    Vue最常用的组件通讯有三种:父->子组件通讯.子->父组件通讯,兄弟组件通讯.(template用的pug模板语法) 1.父->子组件通讯 父->子组件通讯,是通过props ...

  9. 绛河 初识WCF5

    然后我们在<Client>中添加一个终结点,这个是客户端的终结点,我们前面曾经提过,通信实际上发生在两个终结点间,客户端也有个终结点,然而请求总是从客户端首先发起,所以终结点地址应该填写为 ...

  10. ajax实现跨域提交

    因为现在一直用的mvc,所以就以mvc来说说ajax跨域提交. 首先说说跨域,简单说就是不同域名访问,比如在aaa.com访问bbb.com. 就拿招聘网站来说,分为两种用户,求职者和企业,求职者端是 ...