zoukankan      html  css  js  c++  java
  • JNI由浅入深_6_简单对象的应用

    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;
    }


  • 相关阅读:
    双主双写、只备份某些表且要在建表ID自增
    我的系统资源呢?php-fpm你知道吗?
    apache常用的两种工作模式 prefork和worker
    Binlog的三种模式
    Tomcat
    JVM初识、调优
    httpclient 3.1跳过https请求SSL的验证
    POM报错Failure to transfer org.apache.maven.plugins:maven-resources-plugin:pom:2.6 from
    eclipse快捷键,移动和复制一段代码
    org.codehaus.jettison.json.JSONObject使用方法
  • 原文地址:https://www.cnblogs.com/lbangel/p/4335861.html
Copyright © 2011-2022 走看看