c call java的实现方式

来源:互联网 发布:wings知乎 编辑:程序博客网 时间:2024/06/02 12:23

近日,我们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);
}
	
				
		
原创粉丝点击