在JNI调用中调用getFilesDir()时出现NullPointerException
我试图通过JNI调用从C库调用Java的getFilesDir(),并且我遇到了一个我不理解的NullPointerException。 这是例外:
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)
问题出现在这个函数中:
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设置的静态变量:
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, "", "()V"); obj = (*env)->NewGlobalRef(env, (*env)->NewObject(env, cls, constr)); return JNI_VERSION_1_6; }
这是JNI函数本身:
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()有关。 如果我避免调用该函数并传回调试字符串,一切似乎都有效。 我认为问题与没有正确设置Context有关,但我不确定可能出错。
您的MYService类可能扩展了Android服务或活动。 通常不会使用构造函数调用创建这些类。 它们由系统使用Intents启动。 您通常可以在onCreate方法中首次使用完整的“上下文”function。 因此,您应该从其他地方获取对您的MYService的引用 – 而不是通过从JNI实例化它。