在NDK C++线程中如何调用JAVA API
from://http://www.eoeandroid.com/thread-150995-1-1.html
在NDK中创建的线程中, 只允许调用静态的Java API. 当在线程中调用env->FindClass(), 系统就会发出异常.
http://android.wooyd.org/JNIExample中有较详细的调用说明.
示例代码如下:
JAVA 代码:
public class simple_test extends Activity {
...
public static void PrintNdkLog(String slog) {
Log.e("NDK", slog);
}
}
C++ 代码:
static JavaVM* g_JavaVM = NULL;
static jobject g_InterfaceObject = 0;
static void GetInterfaceObject(JNIEnv *env, const char *path, jobject *objptr) {
jclass cls = env->FindClass(path);
if(!cls) {
return;
}
jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
if(!constr) {
return;
}
jobject obj = env->NewObject(cls, constr);
if(!obj) {
return;
}
(*objptr) = env->NewGlobalRef(obj);
}
int JniLoad(JavaVM* jvm, void* reserved)
{
g_JavaVM = jvm;
JNIEnv *env;
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
GetInterfaceObject(env, "com/myndk/simple_test", &g_InterfaceObject);
return JNI_VERSION_1_6;
}
void JniUnLoad(JavaVM* jvm, void* reserved)
{
JNIEnv *env;
if (jvm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
return;
}
env->DeleteGlobalRef(g_InterfaceObject);
}
void PrintNdkLog(const char *format, ...)
{
va_list arg_ptr;
char sLogBuff[1024];
va_start(arg_ptr, format);
vsprintf(sLogBuff, format, arg_ptr);
va_end(arg_ptr);
if (g_JavaVM == NULL)
return;
int status;
JNIEnv *env = NULL;
bool isAttached = false;
status = g_JavaVM->GetEnv((void**) &env, JNI_VERSION_1_6);
if(status < 0)
{
status = g_JavaVM->AttachCurrentThread(&env, NULL);
if(status < 0)
{
return;
}
isAttached = true;
}
jclass cls = env->GetObjectClass(g_InterfaceObject);
if (cls != 0)
{
jmethodID mid = env->GetStaticMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V");
if (mid != 0)
{
jstring jstrMSG = env->NewStringUTF(sLogBuff);
env->CallStaticVoidMethod(cls, mid, jstrMSG);
}
}
if (isAttached) // From native thread
{
g_JavaVM->DetachCurrentThread();
}
}