android – 如何从NDK C线程调用Java API?

前端之家收集整理的这篇文章主要介绍了android – 如何从NDK C线程调用Java API?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想从NDK C线程调用 Java API,但env-> FindClass()返回0.但是当我在主线程中调用Java API时,它工作得很好.我已经在线程中调用了AttachCurrentThread(),任何人都可以帮我吗?

这是源代码

JAVA代码

public class simple_test extends Activity {
    ...
    // This functin will be called in C++
    public void PrintNdkLog(String slog) {
        Log.e(logTagNDK,slog);
        return;
    }
}

C代码

static JavaVM* g_JavaVM = NULL;

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;
}

// JNI OnLoad
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm,void* reserved)
{
    g_JavaVM = jvm;
    return JNI_VERSION_1_6;
}

// Call JAVA API "PrintNdkLog" in this function
void PrintNdkLog(char *lpLog)
{
    if (g_JavaVM == NULL)
        return;

    JNIEnv *env = NULL;
    g_JavaVM->GetEnv((void**)&env,JNI_VERSION_1_6);
    if (env == NULL)
        return;

    jclass cls = env->FindClass("com/myndk/simple_test");
    if (cls != 0) // **cls will be 0 when PrintNdkLog() is called in thread**
    {
        LOGE("FindClass error %p",cls);
    }
    else
    {
        jmethodID mid;
        jobject obj;
        obj = getInstance(env,cls);
        mid = env->GetMethodID(cls,"PrintNdkLog","(Ljava/lang/String;)V");
        if (mid != 0)
        {
            jstring jstrMSG = env->NewStringUTF(lpLog);
            env->CallVoidMethod(obj,mid,jstrMSG);
        }
    }
}

// Call JAVA API in thread
static void* thread_test(void* ptr)
{
    JNIEnv *envLocal;
    int status = g_JavaVM->GetEnv((void **) &envLocal,JNI_VERSION_1_6);
    if (status == JNI_EDETACHED)
    {
        status = g_JavaVM->AttachCurrentThread(&envLocal,NULL);
        if (status != JNI_OK)
            LOGE("AttachCurrentThread Failed %d",status);
    }
    PrintNdkLog("bbb"); // This JAVA callback Failed,and printed "FindClass error"
}

// Create thread
int NdkThread(AFX_THREADPROC pfnThreadProc,LPVOID pParam,int nPriority)
{
    PrintNdkLog("aaa"); // This JAVA callback runs well
    pthread_t pid;
    pthread_create(&pid,NULL,thread_test,pParam);
}

解决方法

我现在解决
在NDK本机线程中,只能调用静态Java API.如果调用env-> FindClass(),它将触发异常.
http://android.wooyd.org/JNIExample获得了细节信息.

猜你在找的Android相关文章