您的位置:首页 > 编程语言 > C语言/C++

在NDK C++线程中如何调用JAVA API

2015-02-27 15:57 453 查看
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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: