0
我試圖通過JNI調用從C庫調用Java的getFilesDir(),並且遇到我不明白的NullPointerException。這裏的例外:在JNI調用中調用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, "<init>", "()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()有關。如果我避免調用該函數並傳回一個調試字符串,那麼一切似乎都有效。我認爲這個問題與沒有正確設置上下文有關,但我不確定什麼可能是錯誤的。
我認爲你是正確的。您的MyService類可能擴展了Service或Activity。這些類不是用它們的構造函數調用創建的。它們由系統使用意圖啓動。您通常可以在其onCreate方法中使用完整的「上下文」功能。所以你應該從別的地方得到你的MyService的引用 - 而不是通過實例化它。 –
謝謝,這有幫助。我在onCreate('mContext = this;)中保存了上下文,然後在getFilesDirPath()函數('mContext.getFilesDir()。getPath()')中使用它。請發表您的評論作爲答案,我會很樂意給你信用。 – GrandAdmiral