我有一个扩展Application的类,名为MyApplicaton,用于存储全局变量,即我希望能够在我的Android应用程序中随处访问的变量。
在活动中,我可以通过调用
来访问MyApplicationmyapp = (MyApplication) this.getApplication();
我想将一些变量存储到文件中,并能够从文件中读取它们。 现在,如果我从MyApplication构造函数中调用readFromStorage(),我会得到一个NullPointerException(下面的日志)。但是,如果我不从构造函数中调用readFromStorage(),但稍后说,例如在调用writeToStorage之后(而不是从构造函数中调用),则执行正常。
如果文件不存在,我希望看到FileNotFoundException。但这并没有被抛出。
这是MyApplication,它扩展了Application。滚动到底部查看我的writeToStorage和readFromStorage()方法。
public class MyApplication extends Application {
private static String FILENAME = "globs";
private static int CONTEXT = Context.MODE_PRIVATE;
private String value1 = new String();
private String value2 = new String();
public MyApplication(){
//check for and load stored globals in internal storage
Log.v("Here", "In MyApplication constructor");
readFromStorage();
}
//Took out unnecessary getter and setters for this question
private void writeToStorage(){
//Create JSON object
Log.v("Here", "In MyApplication writeToStorage");
JSONObject obj = new JSONObject();
File f = new File(FILENAME);
OutputStream out;
try {
obj.put("value1", value1);
obj.put("value2", value2);
FileOutputStream fos = openFileOutput(FILENAME, CONTEXT);
fos.write(obj.toString().getBytes());
fos.close();
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//We've just written to the file. Lets see if we can read from it...
this.readFromStorage();
}
public void readFromStorage(){
Log.v("Here", "In MyApplication readFromStorage");
try {
Log.v("Here", "FILENAME: "+ FILENAME);
FileInputStream out = openFileInput(FILENAME);
BufferedReader inputReader = new BufferedReader(new InputStreamReader(out));
String inputString;
StringBuffer sb = new StringBuffer();
while ((inputString = inputReader.readLine()) != null) {
sb.append(inputString + "\n");
}
JSONObject jsonObject = new JSONObject(sb.toString());
this.value1 = (String) jsonObject.get("value1");
this.value2 = (String) jsonObject.get("value2");
out.close();
inputReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
导致nullpointer异常的行是:
FileInputStream out = openFileInput(FILENAME);
FILENAME不为null,我在调用之前用Log语句检查它。
这是日志输出:
03-26 13:08:05.462: V/Here(26212): In MyApplication constructor
03-26 13:08:05.462: V/Here(26212): In MyApplication readFromStorage
03-26 13:08:05.462: V/Here(26212): FILENAME: globs
03-26 13:08:05.462: W/dalvikvm(26212): threadid=1: thread exiting with uncaught exception (group=0x41fb62d0)
03-26 13:08:05.462: E/AndroidRuntime(26212): FATAL EXCEPTION: main
03-26 13:08:05.462: E/AndroidRuntime(26212): java.lang.RuntimeException: Unable to instantiate application com.example.tetherly.MyApplication: java.lang.NullPointerException
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.LoadedApk.makeApplication(LoadedApk.java:553)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4795)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.ActivityThread.access$1300(ActivityThread.java:151)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.os.Handler.dispatchMessage(Handler.java:99)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.os.Looper.loop(Looper.java:155)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.ActivityThread.main(ActivityThread.java:5485)
03-26 13:08:05.462: E/AndroidRuntime(26212): at java.lang.reflect.Method.invokeNative(Native Method)
03-26 13:08:05.462: E/AndroidRuntime(26212): at java.lang.reflect.Method.invoke(Method.java:511)
03-26 13:08:05.462: E/AndroidRuntime(26212): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
03-26 13:08:05.462: E/AndroidRuntime(26212): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
03-26 13:08:05.462: E/AndroidRuntime(26212): at dalvik.system.NativeStart.main(Native Method)
03-26 13:08:05.462: E/AndroidRuntime(26212): Caused by: java.lang.NullPointerException
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.content.ContextWrapper.openFileInput(ContextWrapper.java:159)
03-26 13:08:05.462: E/AndroidRuntime(26212): at com.example.tetherly.MyApplication.readFromStorage(MyApplication.java:106)
03-26 13:08:05.462: E/AndroidRuntime(26212): at com.example.package.MyApplication.<init>(MyApplication.java:32)
03-26 13:08:05.462: E/AndroidRuntime(26212): at java.lang.Class.newInstanceImpl(Native Method)
03-26 13:08:05.462: E/AndroidRuntime(26212): at java.lang.Class.newInstance(Class.java:1319)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.Instrumentation.newApplication(Instrumentation.java:988)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.Instrumentation.newApplication(Instrumentation.java:973)
03-26 13:08:05.462: E/AndroidRuntime(26212): at android.app.LoadedApk.makeApplication(LoadedApk.java:544)
03-26 13:08:05.462: E/AndroidRuntime(26212): ... 11 more
答案 0 :(得分:3)
您在构造函数中过早使用Application
作为Context
。它未在应用生命周期Context
之前设置为onCreate()
使用。
基本上,初始化有三个与此问题相关的步骤:
实例化对象。
在对象中设置资源和上下文。
在对象上调用onCreate()
。
在第1步实例化(构造函数,成员变量),该对象尚不可用作Context
。
这同样适用于活动和服务:您只能在Context
或更晚的时候将其用作onCreate()
。
答案 1 :(得分:0)
问题是您的应用程序上下文为空。
在MyApplication构造函数中,您没有调用super(),因此未正确创建应用程序。
public MyApplication(){
super();
//check for and load stored globals in internal storage
Log.v("Here", "In MyApplication constructor");
readFromStorage();
}