java文件中我定义了一个方法CallBack_Msg.在C中调用.
package com.javajnicallback;
....
public class MainActivity extends ActionBarActivity
{
public static void CallBack_Msg(String msg)
{
tv1.setText(msg);
}
}
C中是这样的
static JavaVM* gJavaVM;
//gJavaVM 通过AndroidRuntime::getRuntime获取到了.
int GetJNIEnv(JNIEnv** pEnv)
{
jint result=0;
JavaVMAttachArgs args={0};
result=(*gJavaVM)->GetEnv(gJavaVM,(void**)pEnv,JNI_VERSION_1_4);
if(result == JNI_EDETACHED)
{
result = (*gJavaVM)->AttachCurrentThread(gJavaVM,pEnv,NULL);
if (result != JNI_OK)
{
log("NOTE: attach of thread failed\n");
return JNI_ERR;
}
return 1;
}
else
if (result != JNI_OK)
return JNI_OK;
else
return JNI_ERR;
}
void __attribute__ ((constructor)) my_init(void);
void my_init(void)
{
//获取JNIEnv对象
JNIEnv *env = 0;
int ndeatch=GetJNIEnv(&env);
if(env)
{
//查找类 package com.javajnicallback;
jclass javajnicallback;
jmethodID CallBack_Msg;
javajnicallback = (*env)->FindClass(env,"com/javajnicallback/MainActivity");
if(javajnicallback)
{
// public void CallBack_Msg(String msg)
CallBack_Msg = (*env)->GetStaticMethodID(env, javajnicallback,"CallBack_Msg","(Ljava/lang/String;)V");
log("CallBack_Msg:%x" ,(unsigned int)CallBack_Msg);
}
}
}
void
Java_com_javajnicallback_MainActivity_sayhi(JNIEnv* env
,jobject thiz)
{
//查找类 package com.javajnicallback;
jclass javajnicallback;
jmethodID CallBack_Msg;
javajnicallback = (*env)->FindClass(env,"com/javajnicallback/MainActivity");
if(javajnicallback)
{
// public void CallBack_Msg(String msg)
CallBack_Msg = (*env)->GetStaticMethodID(env, javajnicallback,"CallBack_Msg","(Ljava/lang/String;)V");
log("CallBack_Msg:%x" ,(unsigned int)CallBack_Msg);
}
}
程序编译完成.
现在问题是 so在加载时my_init中执行
(*env)->FindClass(env,"com/javajnicallback/MainActivity");
会找不到类.
java.lang.NoClassDefFoundError:[generic]
但是Java调用Java_com_javajnicallback_MainActivity_sayhi就能找到类.
请问这要如何解决?
//////////////////////////////////////////////////////////////////////
还有个问题so中从线程中调用java 方法CallBack_Msg
线程代码:
void *thread_fun(void* arg)
{
//获取JNIEnv对象
JNIEnv *env = 0;
int ndeatch=GetJNIEnv(&env);
//查找类 package com.javajnicallback;
jclass javajnicallback;
jmethodID CallBack_Msg;
javajnicallback = (*env)->FindClass(env,"com/javajnicallback/MainActivity");
if(javajnicallback)
{
CallBack_Msg = (*env)->GetStaticMethodID(env, javajnicallback,"CallBack_Msg","(Ljava/lang/String;)V");
log("CallBack_Msg:%x" ,(unsigned int)CallBack_Msg);
}
jstring msg=(*env)->NewStringUTF(env, "call back msg.");
//public void CallBack_Msg(String msg)
//这种情况下.如何传 obj
(*env)->CallStaticVoidMethod(env, obj,CallBack_Msg,msg);
}
请指点!
------解决思路----------------------
你不能直接找Activity 自己去实例化这个类,JNI里面找不到环境引用,你可以自己实例化一个类 然后把this引用传过来。
------解决思路----------------------
问题1: env不是主线程的env 不能获取自定义的类,可以在主线程中调用 env->NewGlobalRef(object);创建一个全局引用,供线程调用.这样就能找到自定义的类和方法了。
问题2:同样 你每次调用Jni方法的时候会传递env和obj过来,obj就是this对象,
如 void RequestAD(JNIEnv* env,jobject object,jstring jstrUrl) 同样你在其他的线程中使用的话调用NewGlobalRef创建全局引用,在不在使用的时候调用env->DeleteGlobalRef删除全局引用,要不然java对象不会释放造成内存泄露。