JNI本身并不复杂,难点在于类型转换上,下就对类型转换进行一个总结。
1、基本类型,直接转换
static jbyte byte_test_jni(JNIEnv *env, jclass clazz, jbyte bt) { LOGD("%s:%u, static_use_byte!------bt :%d", __func__, __LINE__,(int)bt); jbyte ret = 't'; return ret; }
2、返回String
static jstring static_hello_jni(JNIEnv *env, jclass clazz) { LOGD("%s:%u, static_hello", __func__, __LINE__); return (env)->NewStringUTF("static hello jni."); }
(1)通过实例对象获取类
(2)通过类获得方法与字段ID
(3)进行处理
static void class_arg_test_jni(JNIEnv *env, jclass clazz, jobject obj) { LOGD("%s:%u, class_arg_test_jni", __func__, __LINE__); //通过实例对象获取类 jclass objClass = env->GetObjectClass(obj); if(objClass) { /***通过类获取字段ID**********int*****/ jfieldID intID = env->GetFieldID(objClass,"nValue","I"); /***通过字段ID获取对象实例字段的值*********/ jint nValue = (int)env->GetIntField(obj,intID); LOGD("%s:%u, class_arg_test_jni, nValue :%d", __func__, __LINE__, nValue ); /*****设置对象实例的字段的值********/ env->SetIntField(obj,intID,222); //str jfieldID strID = env->GetFieldID(objClass,"strValue","Ljava/lang/String;"); jstring str = env->NewStringUTF("XXXXXXXXXXXXOOOOOOOOOOOOOOOOO"); env->SetObjectField(obj,strID,str); //array-----------如何设置nArr呢 jfieldID intArrID = env->GetFieldID(objClass,"nArr","[I"); jint nArr[8] = {8,7,6,5,4,3,2,1}; jintArray jnArray = env->NewIntArray(8); env->SetIntArrayRegion(jnArray,0,8,nArr); env->SetObjectField(obj,intArrID,jnArray); //处理enum对象 /*******1、通过类获得字段ID***************/ jfieldID enumID = env->GetFieldID(objClass,"mdate","Lcom/example/data/TestClass$DateIn;"); /*******2、通过ID获取实例对象相应字段的值(对象实例)************/ jobject jenum = (jclass)env->GetObjectField(obj,enumID); if(jenum == NULL) { LOGD("%s:%u, get enum failed", __func__, __LINE__); return; } LOGD("%s:%u, ok", __func__, __LINE__ ); /********3、通过类获取方法ID**************/ jclass jenumClass = (env)->FindClass("com/example/data/TestClass$DateIn"); jmethodID getVal = env->GetMethodID(jenumClass, "name", "()Ljava/lang/String;"); jstring value = (jstring)env->CallObjectMethod(jenum, getVal); const char * valueNative = env->GetStringUTFChars(value, 0); if (strcmp(valueNative, "MONDAY") == 0) LOGI("%s:%u, TODAY IS MONDAY!", __func__, __LINE__); else if(strcmp(valueNative, "TUESDAY") == 0) LOGI("%s:%u, TODAY IS NOT TUESDAY!", __func__, __LINE__); else LOGI("%s:%u, TODAY", __func__, __LINE__); } }
static jobject class_return_test_jni(JNIEnv *env, jclass clazz) { LOGD("%s:%u, class_return_test_jni", __func__, __LINE__); //通过实例对象获取类 jclass objectClass = (env)->FindClass("com/example/data/TestClass"); //通过类获得构造函数 jmethodID mid = (env)->GetMethodID(objectClass,"<init>","()V"); /*********生成java中的类TestClass********/ jobject m_obj = env->NewObject(objectClass,mid); LOGI("%s:%u, static_deal----GetMethodID", __func__, __LINE__ ); /*******************通过类获取字段ID******************/ jfieldID ival = (env)->GetFieldID(objectClass,"nValue","I"); //jfieldID strID = env->GetFieldID(objectClass,"strValue","Ljava/lang/String;"); /*****************在jni层操作java类中的变量*****************/ (env)->SetIntField(m_obj,ival,100); return m_obj; }
void enum_arg_test_jni(JNIEnv *env, jclass clazz, jobject obj2) { LOGD("%s:%u, enum_arg_test_jni", __func__, __LINE__); //通过对象实例来获取类 jclass enumclass= env->GetObjectClass(obj2); if(enumclass == NULL) { LOGD("%s:%u, get enum failed", __func__, __LINE__); return; } //name()函数是enum类型自带的函数,()Ljava/lang/String;是对应的签名 //1、通过类获取方法ID jmethodID getVal = env->GetMethodID(enumclass, "name", "()Ljava/lang/String;"); //2、获取根据ID方法,调用实例的name()方法 jstring value = (jstring)env->CallObjectMethod(obj2, getVal); const char * valueNative = env->GetStringUTFChars(value, 0); if (strcmp(valueNative, "MONDAY") == 0) LOGI("%s:%u, TODAY IS MONDAY!", __func__, __LINE__); else if(strcmp(valueNative, "TUESDAY") == 0) LOGI("%s:%u, TODAY IS NOT TUESDAY!", __func__, __LINE__); else LOGI("%s:%u, TODAY", __func__, __LINE__); }