第一章: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 }