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