第一章:C調java
第一種:訪問java中的非靜態方法
1.jclass clz=(*env)->GetObjectClass(env,jobj)
//獲取簽名
2.jmethodID mid=(*env)->GetMethodID(env,jclz,"方法名","簽名");
3.jint num=(*env)->CallIntMethod(env,job,mid,200);
第二種:訪問java中的靜態方法
1.jclass clz=(*env)->GetObjectClass(env,jobj)
//獲取簽名
2.jmethodID jmid=(*env)->GetStaticMethodID(env,clz,"方法名",“簽名”);
3.jstring uuid=(*env)->callStaticObjectMethod(env,clz,jmid)
第三種:訪問java中的構造方法
//找到對應的類
1.jclass jclz=(*env)->FindClass(env,jobj):
//獲取要調用對象中的方法的方法ID
4.jmethodID time_mid=(*env)->GetMethodID(env,jcld,"getTime","()L");
//調用方法
5.jlong time=(*env)->CallLongMethod(env,date_obj,time_mid);
char * stringChar(JNIEnv* env){ char* c_str="上課的時間空間"; jclass str_cls=(*env)->FindClass(env,"java/lang/String"); jmethodID jmid=(*env)->GetMethodID(env,str_cls,"<init>","([BLjava/lang/String:)V"); jbyteArray bytes=(*env)->NewByteArray(env,strlen(c_str)); // 將字符串從0開始拷貝到bytes中 (*env)->SetByteArrayRegion(env,bytes,0,strlen(c_str),c_str); jstring strencode=(*env)->NewStringUTF(env,"GB2312"); return (*env)->NewObject(env,str_cls,jmid,bytes,strencode); }
//引用數據類型的數組 /** * 1.create jobject array * 2.eva * 3.return; */ JNIEXPORT jobjectArray JNICALL Java_mdks_com_mvp_jni_JNITest_initStringArray(JNIEnv *env, jobject jobj, jint size) { jobjectArray result; jclass jclz; jclz=(*env)->FindClass(env,"java/lang/String"); if (jclz==NULL){ return NULL; } result=(*env)->NewObjectArray(env,size,jclz,jobj); //eva if (result==NULL){ return NULL; } for (int i = 0; i < size;i++) { char* c_str=(char*)malloc(256); memset(c_str,0,256); //將int 轉化成爲char sprintf(c_str,"hello num:%d\n",i); //c->jstring jstring str=(*env)->NewStringUTF(env,c_str); if (str==NULL){ return NULL; } //將jstring 給數組 (*env)->SetObjectArrayElement(env,result,i,str); free(c_str); c_str=NULL; (*env)->DeleteGlobalRef(env,str); } // TODO return result; }
引用:
//局部引用 //定義方式多樣:FindClass NewObject ,GetObjectClass,NewCharArray.... //NewLocalRef //釋放方式:1.方法調用完JVM 會自動釋放 2.手動釋放:DeleteLocalRef //不能在多線程中使用 JNIEXPORT void JNICALL Java_mdks_com_mvp_jni_JNITest_localRef(JNIEnv *env, jobject instance) { int i=0; for (int i = 0; i <5 ; ++i) { jclass cls=(*env)->FindClass(env,"java/util/Date"); jmethodID jmid=(*env)->GetMethodID(env,cls,"<init>","()V"); //創建局部引用 jobject obj=(*env)->NewObject(env,cls,jmid); //使用引用 //釋放引用 (*env)->DeleteLocalRef(env,cls); (*env)->DeleteLocalRef(env,obj); } // TODO }
//全局引用----跨線程,跨方法 jstring global_str; JNIEXPORT void JNICALL Java_mdks_com_mvp_jni_JNITest_createGlobalRef(JNIEnv *env, jobject instance) { jobject obj=(*env)->NewStringUTF(env,"instance "); global_str=(*env)->NewGlobalRef(env,obj); // TODO } JNIEXPORT jstring JNICALL Java_mdks_com_mvp_jni_JNITest_getGlobalRef(JNIEnv *env, jobject instance) { // TODO return global_str; } JNIEXPORT void JNICALL Java_mdks_com_mvp_jni_JNITest_delGlobalRef(JNIEnv *env, jobject instance) { // TODO (*env)->DeleteGlobalRef(env,global_str); } //弱全局引用 //它不會阻止GC,/跨線程,跨方法使用 jclass g_weak_cls; JNIEXPORT jstring JNICALL Java_mdks_com_mvp_jni_JNITest_createWeakRef(JNIEnv *env, jobject instance) { jclass cls_string=(*env)->FindClass(env,"java/lang/String"); g_weak_cls=(*env)->NewWeakGlobalRef(env,cls_string); // TODO return g_weak_cls; }
異常:
//JNI 異常處理 JNIEXPORT void JNICALL Java_mdks_com_mvp_jni_JNITest_exception(JNIEnv *env, jobject instance) { jclass cls=(*env)->GetObjectClass(env,instance); jfieldID fid=(*env)->GetFieldID(env,cls,"kjdslfj","Ljava/lang/String:"); jthrowable ex=(*env)->ExceptionOccurred(env); //判斷異常是否發送 if(ex!=NULL){ jclass newExce; //清空JNI產生的異常 (*env)->ExceptionClear(env); newExce=(*env)->FindClass(env,"java/lang/IllegalArgumentException"); if (newExce==NULL){ printf("exception\n"); return ; } (*env)->ThrowNew(env,newExce,"Throw exception from JNI: GetFieldID"); } // TODO printf("exception\n"); }
//局部靜態變量進行緩存 JNIEXPORT void JNICALL Java_mdks_com_mvp_jni_JNITest_cached(JNIEnv *env, jobject instance) { jclass cls=(*env)->GetObjectClass(env,instance); static jfieldID fid; if (fid==NULL){ fid=(*env)->GetFieldID(env,cls,"key","Ljava/lang/String:"); printf("GetFieldId\n"); } // TODO }