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. H5实现拍照上传功能

    <input type="file" capture="camera" accept="image/*" >

  2. drupal 通过hook_menu实现添加菜单

    $items['mypayment/onlinepay']=array( 'title' => '在线充值', 'description' => '在线充值', 'page callbac ...

  3. <!DOCTYPE> 标签是什么

    DOCTYPE 标签,是html文档的类型声明(document type declaration,所谓声明,也就是宣称我他妈是谁),用来告诉浏览器,使用什么样的文档类型定义(Document Typ ...

  4. Python 循环删除指定文件夹下所有的.longtian类型文件

    # -*- coding: utf-8 -*- import os #遍历文件夹删除文件 def traversing_dir(rootDir): #遍历根目录 for root,dirs,files ...

  5. 【javascript】javascript设计模式之工厂模式

    1.要解决的问题 2.如何实现 3.与构造函数的区别 4.总结 1.要解决的问题 工厂模式通常用于重复创建相似对象,提供动态创建对象的接口. 2.工厂模式最为设计模式中构造模式之一,通常在类或类的静态 ...

  6. Python FFT (Fast Fourier Transform)

    np.fft.fft import matplotlib.pyplot as plt import plotly.plotly as py import numpy as np # Learn abo ...

  7. Linux下部署redis以及相关简介

    什么是redis? Redis是一个高性能的key-value数据库.key-value分布式存储系统查询速度快.存放数据量大.支持高并发,非常适合通过主键进行查询,但不能进行复杂的条件查询.key ...

  8. C# winfrom提示框,点击则不显示,不点击则提示输入内容

    先看下效果图,初次进来是界面左边的效果,点击请输入账号,清除内容,可以直接输入,右边图                            以下代码是失去焦点的,一定要把控件的属性TabStop 改 ...

  9. ASP.net Substitution 页面缓存而部分不缓存的实现方法

    在ASP.NET中要实现部分内容非缓存,而其它的都需要缓存输出,可以使用Substitution控件实现. <%@ Page Language="C#" AutoEventW ...

  10. 月报 提取/保存 到OneDrive. 并发送反馈邮件