Search code examples
javaandroidnullpointerexceptionsharedpreferencesandroid-sharedpreferences

What exactly is causing this NullPointerException?


I'm pretty new to Android development and am currently working on an app which is supposed to save the current time and date when a button is pressed, store it to SharedPreferences and then present the String when a different button is pressed. I got it working but did some tinkering today and now I'm getting a NullPointerException that I can't solve, even after having spent about 45 minutes on Google and Stackoverflow trying different code fragments. Can anyone who is better at this than me tell me what I'm missing?

Here is the relevant code:

public class GetTimeStamp extends AppCompatActivity {

    private String date;
    public void setDate (View view){
        DateFormat df = new SimpleDateFormat("dd.MM.yyy 'om' HH:mm");
        date = df.format(Calendar.getInstance().getTime());
    }
    public String getDate(){
        return date;
    }
        SharedPreferences prefs = this.getSharedPreferences("SharedPrefs",       Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_get_time_stamp);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fabSaveTimeStamp);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setDate(view);
                editor.putString("storedDate", date);
                editor.commit();
                Toast.makeText(getBaseContext(), "blablabla", Toast.LENGTH_SHORT).show();
            }
        })
FloatingActionButton fab3 = (FloatingActionButton) findViewById(R.id.fabShowTimeStamp);
        fab3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //retrieve the date from SharedPreferences and store it to a local String
                String retrievedDate = prefs.getString("storedDate", null);
                if (retrievedDate!=null){
                    AlertDialog alertDialog = new AlertDialog.Builder(GetTimeStamp.this).create(); //Read Update
                    alertDialog.setTitle("");
                    alertDialog.setMessage("somemessage" + retrievedDate);
                    alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    });
                    alertDialog.show();
                }else {
                    //create an alert dialog explaining to the user that no date has been saved yet
                    AlertDialog alertDialog = new AlertDialog.Builder(GetTimeStamp.this).create(); //Read Update
                    alertDialog.setTitle("Error");
                    alertDialog.setMessage("errorexplanation");
                    alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    });
                    alertDialog.show();
               }
            }
        });  

And here are the errors:

02-08 22:49:36.142 19735-19735/? W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41ed7ce0)
02-08 22:49:36.152 19735-19735/? E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.example.user.appname, PID: 19735
   java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.user.appname/com.example.user.appname.GetTimeStamp}: java.lang.NullPointerException
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2131)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2264)
       at android.app.ActivityThread.access$800(ActivityThread.java:144)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:136)
       at android.app.ActivityThread.main(ActivityThread.java:5139)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
       at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.NullPointerException
       at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:173)
       at com.example.user.appname.GetTimeStamp.<init>(GetTimeStamp.java:36)
       at java.lang.Class.newInstanceImpl(Native Method)
       at java.lang.Class.newInstance(Class.java:1208)
       at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2122)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2264) 
       at android.app.ActivityThread.access$800(ActivityThread.java:144) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1205) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:136) 
       at android.app.ActivityThread.main(ActivityThread.java:5139) 
       at java.lang.reflect.Method.invokeNative(Native Method) 
       at java.lang.reflect.Method.invoke(Method.java:515) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612) 
       at dalvik.system.NativeStart.main(Native Method)   

Solution

  • You are trying to initialize the following class field before you are allowed to:

    SharedPreferences prefs = this.getSharedPreferences("SharedPrefs",       Context.MODE_PRIVATE);
    

    Only declare the field:

    SharedPreferences prefs;
    

    and then assign it in your onCreate() method:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        prefs = getSharedPreferences("SharedPrefs", Context.MODE_PRIVATE);
        ...
    }