Simon
Simon

Reputation: 504

openFileInput(FILENAME) nullPointerException: FILENAME not null

I have a class that extends Application, called MyApplicaton, that I use to store global variables, i.e., variables I want to be able to access anywhere throughout my android app.

In activites, I get access to MyApplication by calling

myapp = (MyApplication) this.getApplication();

I want to store some of these variable to a file, and be able to read them back from a file. Now, I get a NullPointerException (log below) if I call readFromStorage() from within the MyApplication constructor. However, If I don't call readFromStorage() from the constructor, but say later, for example after writeToStorage has been called (not from the constructor), it executes fine.

If the file doesn't exist, I'd expect to see a FileNotFoundException. But this doesn't get thrown.

Here is MyApplication, which extends Application. Scroll to the bottom to see my writeToStorage and readFromStorage() methods.

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

The line that causes the nullpointer exception is:

FileInputStream out = openFileInput(FILENAME);

FILENAME is not null, which I check with a Log statement prior to calling it.

Here is the log output:

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

Upvotes: 3

Views: 1338

Answers (2)

laalto
laalto

Reputation: 152787

You are using your Application too early as a Context - in constructor. It is not set up for Context use before onCreate() in the app lifecycle.

Basically the initialization has three steps that are relevant to this question:

  1. Instantiate the object.

  2. Set up resources and context in the object.

  3. Call onCreate() on the object.

At step 1 instantiation (constructor, member variables) the object isn't yet usable as a Context.

The same applies to activities and services: you can use them as a Context only at onCreate() or later.

Upvotes: 3

Robby Pond
Robby Pond

Reputation: 73484

The issue is that your Application context is null.

In your MyApplication constructor you are not calling through to super() so your Application is not being created correctly.

public MyApplication(){
    super();
    //check for and load stored globals in internal storage
    Log.v("Here", "In MyApplication constructor");
    readFromStorage();
}

Upvotes: 0

Related Questions