在JNI调用调用getFilesDir()时的NullPointerException [英] NullPointerException when Calling getFilesDir() in a JNI Call

查看:2133
本文介绍了在JNI调用调用getFilesDir()时的NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过JNI调用从C库调用Java的getFilesDir()和我打一个NullPointerException异常,我不明白。这里的异常:

I'm trying to call Java's getFilesDir() from a C library through a JNI call and I'm hitting a NullPointerException that I don't understand. Here's the exception:

W/System.err( 1576): java.lang.NullPointerException
W/System.err( 1576):    at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
W/System.err( 1576):    at MYService.getFilesDirPath(MYService.java:1150)
W/System.err( 1576):    at MYService.UtvGetPeristentPath(Native Method)

问题是发生在这个功能:

The problem is happening in this function:

public String getFilesDirPath()
{
    try {
        return getFilesDir().getPath(); // <--- Exception happens here!
    }
    catch(Exception e)
    {
        e.printStackTrace();
        Log.e("DEBUG", "getFilesDirPath set exception", e);
        return null;
    }
}

该JNI调用设置了由JNI_OnLoad设置一些静态变量:

The JNI call is set up with a few static variables that are set by JNI_OnLoad:

static JavaVM              *s_jvm = NULL;
static jclass cls; 
static jmethodID mid;
static jobject obj;                        

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    s_jvm = vm;
    JNIEnv *env;
    if (s_jvm){
        (*s_jvm)->AttachCurrentThread (s_jvm, &env, NULL);
    }    
    jclass localRef_class;
    jmethodID localRef_mid;
    jmethodID constr; 

    localRef_class = (*env)->FindClass(env, "MYService");
    cls = (*env)->NewGlobalRef(env,localRef_class);

    constr = (*env)->GetMethodID(env, cls, "<init>", "()V"); 
    obj = (*env)->NewGlobalRef(env, (*env)->NewObject(env, cls, constr));

    return JNI_VERSION_1_6; 
}

这里是JNI函数本身:

And here is the JNI function itself:

char *getFilesDirPath() {
    JNIEnv *jenv = NULL;
    __android_log_print(ANDROID_LOG_ERROR, "DEBUG", "JNI_Interface: getFilesDirPath");
    if(s_jvm == NULL)
    return NULL;

    int check = (*s_jvm)->GetEnv(s_jvm,(void **)&jenv,JNI_VERSION_1_6);

    if (check != JNI_OK) {
        (*s_jvm)->AttachCurrentThread(s_jvm, &jenv, NULL);
        (*s_jvm)->GetEnv(s_jvm,(void **)&jenv,JNI_VERSION_1_6);
    }
    if(jenv != NULL)
    {

        // get the method
        mid = (*jenv)->GetMethodID(jenv, cls, "getFilesDirPath", "()Ljava/lang/String;");
        if (mid == 0) {
            __android_log_print(ANDROID_LOG_ERROR, "DEBUG", "getFilesDirPath not found");
            if (check != JNI_OK)
                (*s_jvm)->DetachCurrentThread (s_jvm);
            return NULL;
        }
        else{
            jstring result = (jstring)(*jenv)->CallObjectMethod(jenv, obj, mid);
            char *filesDir = (char *) (*jenv)->GetStringUTFChars(jenv, result, 0);
            if (check != JNI_OK)
                (*s_jvm)->DetachCurrentThread (s_jvm);
            return filesDir;
        }

    }

    if (check != JNI_OK)
        (*s_jvm)->DetachCurrentThread (s_jvm);
    return NULL;
}

问题是绝对依赖于getFilesDir()。如果我避免调用该函数,并传回调试串,一切似乎工作。我认为这个问题是有关不正确设置的背景下,但我不知道什么可能是错误的。

The problem is definitely tied to getFilesDir(). If I avoid calling that function and pass back a debug string, everything seems to work. I think the problem is related to not properly setting up the Context, but I'm not sure what might be wrong.

推荐答案

您的MyService类可能扩展一个Android服务或活动。这些类通常不与他们的构造函数调用创建的。他们通过使用意图系统启动。你通常可以使用其全部语境的功能在他们的onCreate方法的第一次。所以,你应该从别的地方得到关于你的MyService - 通过JNI instanciating岂不

Your MYService class probably extends an Android Service or Activity. These classes are usually not created with their constructor call. They are started by the system using Intents. You can usually use their full 'Context' functionality for the first time in their onCreate methods. So you should get the reference to your MYService from somewhere else - not by instanciating it from JNI.

这篇关于在JNI调用调用getFilesDir()时的NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆