Android NDK中C++调用Java的完整例子,androidndk
Android NDK中C++调用Java的完整例子,androidndk
Android NDK中C++调用Java时,如果是在线程中调用Java API,则只能调用Java静态的API,如果不是在线程中,则既可以调用Java静态API,也可以调用Java类成员API。
http://android.wooyd.org/JNIExample中有较详细的调用说明.
下面是各调用的示例代码:
JAVA 代码:
package com.myndk;
...
public class simple_test extends Activity {
...
public void PrintNdkLog(String slog) { // 成员函数, 不可在线程中被调用
Log.e("NDK", slog);
}
public static void PrintNdkLogThread(String slog) { // 静态函数, 可在主线中被调用
Log.e("NDK-THREAD", slog);
}
}
C++ 代码:
static JavaVM* g_JavaVM = NULL;
static jobject g_InterfaceObject = 0;
static const char *g_JavaClassName = "com/myndk/simple_test";
static jobject getInstance(JNIEnv *env, jclass obj_class)
{
jmethodID c_id = env->GetMethodID(obj_class, "<init>", "()V");
jobject obj = env->NewObject(obj_class, c_id);
return obj;
}
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, g_JavaClassName, &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];
if (g_JavaVM == NULL)
return;
va_start(arg_ptr, format);
vsprintf(sLogBuff, format, arg_ptr);
va_end(arg_ptr);
int status;
JNIEnv *env = NULL;
bool isAttached = false;
status = g_JavaVM->GetEnv((void**) &env, JNI_VERSION_1_6);
if (status < 0) //表示PrintNdkLog是在线程中被调用的
{
status = g_JavaVM->AttachCurrentThread(&env, NULL);
if (status < 0)
{
return;
}
isAttached = true;
}
if (isAttached) // PrintNdkLog在线程中被调用, 调用Java静态API
{
jclass cls = env->GetObjectClass(g_InterfaceObject);
if (cls != 0)
{
jmethodID mid = env->GetStaticMethodID(cls, "PrintNdkLogThread", "(Ljava/lang/String;)V");
if (mid != 0)
{
jstring jstrMSG = env->NewStringUTF(sLogBuff);
env->CallStaticVoidMethod(cls, mid, jstrMSG);
}
}
g_JavaVM->DetachCurrentThread();
}
else // PrintNdkLog不是在线程中被调用, 调用Java类成员API
{
jclass cls = env->FindClass(g_JavaClassName);
if (cls != 0)
{
jobject obj = getInstance(env, cls);
jmethodID mid = env->GetMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V");
if (mid != 0)
{
jstring jstrMSG = env->NewStringUTF(sLogBuff);
env->CallVoidMethod(obj, mid, jstrMSG);
}
}
}
}
相关文章
- 暂无相关文章
用户点评