c call java的实现方式

近日,我们WifiDisplay的项目中,有需要用到C call Java的代码,我不太能够懂得如何能够实现C call Java,所以我就向我们公司的一帮牛人请教了下,只是简单的写了一个C call Java的实例。

代码:

1.我首先是在java中写了一个调用C层代码的方法,名字叫nativeSetup的方法

public static native void nativeSetup(Object obj);

之后在java中的activity中的onCreate方法中调用它:

nativeSetup(this);

通过这个方法将一个activity的对象传入C层中;

2.在C层中,通过实现nativeSetup(Object),来得到上层Java代码中的对象,从而能够得到methodID,再通过CallStaticMethod方法,调用Java层的方法,具体实现:

static jobject player = NULL;
static JavaVM* gJavaVM = NULL;
extern "C" {   
 JNIEXPORT void JNICALL Java_com_uv_renderer_ProvisionActivity_nativeSetup(JNIEnv *env, jobject obj, jobject param);
}

JNIEXPORT void JNICALL Java_com_uv_renderer_ProvisionActivity_nativeSetup(JNIEnv *env, jobject obj, jobject param){
	player = env->NewGlobalRef(param);
	env->GetJavaVM(&gJavaVM);
	

if (env->ExceptionOccurred()) {

 return;  }

  if(gJavaVM == NULL)  {   env->GetJavaVM(&gJavaVM);   if (env->ExceptionOccurred())   {    return;   }  }

  if (env->ExceptionOccurred())  {   return;  }

  __android_log_print(ANDROID_LOG_INFO, "ProvisionActiity","C : ProvisionActiity : nativeSetup called");


 
void callVoidMethod(char* ch){
	JNIEnv* myEnv = NULL;
 	gJavaVM->AttachCurrentThread(&myEnv, NULL);
 	jclass cls = myEnv->GetObjectClass(player);
 	jmethodID method = myEnv->GetStaticMethodID(cls, "callVoidMethod","(Ljava/lang/String;)V");

  if (myEnv != NULL && cls != NULL && method != NULL) {    __android_log_print(ANDROID_LOG_INFO, "ProvisionActivity","C : ProvisionActivity : callVoidMethod : called begin");    jstring str = toJString(myEnv, ch);    myEnv->CallStaticVoidMethod(cls, method, str);    if (myEnv->ExceptionOccurred()) {     gJavaVM->DetachCurrentThread();     return;    }    gJavaVM->DetachCurrentThread();   }

  __android_log_print(ANDROID_LOG_INFO, "ProvisionActivity","C : ProvisionActivity : callVoidMethod : called end");

}
 
int callIntMethod(){
	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivityC : ProvisionActivity : callIntMethod : called start");
 	int intNumber= -1;

  JNIEnv* myEnv = NULL;   gJavaVM->AttachCurrentThread(&myEnv, NULL);   jclass cls = myEnv->GetObjectClass(player);   jmethodID methodId = myEnv->GetStaticMethodID(cls, "callIntMethod", "()I");

  if (myEnv != NULL && cls != NULL && methodId != NULL) {    intNumber = myEnv->CallStaticIntMethod(cls, methodId);    if (myEnv->ExceptionOccurred()) {      gJavaVM->DetachCurrentThread();     return -1;    }    gJavaVM->DetachCurrentThread();

  }   __android_log_print(ANDROID_LOG_INFO, "ProvisionActivity","C : ProvisionActivity : callIntMethod : called end");   return intNumber;

}
 
const char* callStringMethod(){
	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivty","C : ProvisionActivity : callStringMethod : called start");
 	const char* ch = NULL;
 	JNIEnv* myEnv = NULL;
 	gJavaVM->AttachCurrentThread(&myEnv, NULL);
 	jclass cls = myEnv->GetObjectClass(player);

  jmethodID methodId = myEnv->GetStaticMethodID(cls, "callStringMethod", "()Ljava/lang/String;");   jstring str =NULL;

if (myEnv != NULL && cls != NULL && methodId != NULL) {

   str = (jstring)(myEnv->CallStaticObjectMethod(cls, methodId));

     if (str != NULL)      ch = myEnv->GetStringUTFChars(str, 0);

 

      if (myEnv->ExceptionOccurred()) {     gJavaVM->DetachCurrentThread();     return NULL;    }    gJavaVM->DetachCurrentThread();

	}
	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivty","C : ProvisionActivity : callStringMethod : called end");
	return ch;
}
 
void callVoidMethod(char* first,char* second){
	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivty","C : ProvisionActivity : callVoidMethod(char*,char*) : called start");
	

if (player== NULL) {     return;   }   JNIEnv* myEnv = NULL;   gJavaVM->AttachCurrentThread(&myEnv, NULL);

  jclass cls = myEnv->GetObjectClass(player);   jmethodID method = myEnv->GetStaticMethodID(cls, "callVoidMethod","(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V");   if (myEnv && cls && method) {    jstring jarg1 = myEnv->NewStringUTF((const char*) first);    jstring jarg2 = myEnv->NewStringUTF((const char*) second);    myEnv->CallStaticVoidMethod(cls, method, player, jarg1, jarg2);    if (myEnv->ExceptionOccurred()) {     gJavaVM->DetachCurrentThread();     return;    }    gJavaVM->DetachCurrentThread();   }

	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivty","C : ProvisionActivity : callVoidMethod(char*,char*) : called end");
}


好了,C call Java的调用就已经结束了。

最后再附个将jstring转化为char*的方法:

jstring toJString(JNIEnv* env, char* pat) {
	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivity","C : ProvisionActivity : toJString called start");
	jclass strClass = env->FindClass("java/lang/String");
	jmethodID ctorID = env->GetMethodID(strClass, "<init>","([BLjava/lang/String;)V");
	jbyteArray bytes = env->NewByteArray(strlen(pat));
	env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*) pat);
	jstring encoding = env->NewStringUTF("utf-8");
 
	__android_log_print(ANDROID_LOG_INFO, "ProvisionActivity","C : ProvisionActivity : toJString called end");
	return (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
}





   

你可能感兴趣的:(java,java,java,c,c,android,android,jni,jni)