NullPointerException in SharedPreferences Android

34,814

Solution 1

getSharedPreferences() can only be called after onCreate() has been called on an Activity. Your Prefs class is strangely used in onOptionsItemSelected(). In general, you don't instantiate activities yourself. If your Prefs class is not an actual Activity but a helper class for accessing preferences, pass a Context object to your methods, like this:

public void editRegion(Context ctx, String sregion) {
    SharedPreferences settings = ctx.getSharedPreferences(PREFS_NAME,0);
    SharedPreferences.Editor ed = settings.edit();
    ed.clear();
    ed.putString(region,sregion);
    ed.commit();
}

and call it by:

pob.editRegion(this, "uk");

from your onOptionsItemSelected() method.

Solution 2

I was having the same thing, and I wasn't able to get an accurate answer for my problem until I came into Stephan's answer. However I want to make it even clearer for the next to come:

I was trying to get an access to the shared preferences outside of the activity by using an external class which did not extend the Activity Class. This caused me the same java.lang.NullPointerException.

My Main Activity was creating an object which needed the Context to access the shared preferences:

   ...
   ...
   MyClass myClass = new MyClass (this);

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

As you could see the MyClass creation is done before onCreate is being called, this led the context to be "Half-Baked" and to throw the java.lang.NullPointerException.

Why "Half-Baked"? While debugging the problem, I had a breakpoint on the line

mSharedPreferences = 
        context.getSharedPreferences(PREF_FILE, context.MODE_PRIVATE);

and while inspecting the context parameter I was able to see its values (some of those anyway) giving the false belief that the parameter was fully initialized.

Moving the initialization of myClass into the onCreate event solved the problem:

   ...
   ...
   MyClass myClass;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        myClass = new MyClass (this);
    }
Share:
34,814
Broo
Author by

Broo

Updated on September 08, 2021

Comments

  • Broo
    Broo over 2 years

    My first time using sharedPreferences and i can't seem to get past this error. I have a submenu that is supposed to allow the user to set their region. This should open the correct region activity and be stored and recalled when the app is opened again. I've been going round in circles many times so some of the code will be a bit wierd. I've been focusing on changing from US (default)to UK.

    In the DDMS I'm getting this:

    05-13 11:22:39.344: ERROR/AndroidRuntime(960): java.lang.NullPointerException
    05-13 11:22:39.344: ERROR/AndroidRuntime(960):     at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:146)
    05-13 11:22:39.344: ERROR/AndroidRuntime(960):     at com.silifeform.android.Prefs.editRegion(Prefs.java:29)
    05-13 11:22:39.344: ERROR/AndroidRuntime(960):     at com.silifeform.android.dog.onOptionsItemSelected(dog.java:344)
    

    My code is this:

    public class Prefs extends Activity {
    public static final String PREFS_NAME="LocalePrefs";
    private String region;
    public boolean isUk;
    public boolean isUs;
    public boolean isEu;
    
    @Override
    protected void onCreate(Bundle state) {
        super.onCreate(state);
    
        //restore prefs
        SharedPreferences settings= getSharedPreferences(PREFS_NAME,0);
        String myRegion = settings.getString(region,"us");
    
        this.region=myRegion;
        changeLocale(getRegion());
    }
    
    public void editRegion(String sregion) {
    // The error occurs here:
        SharedPreferences settings = getSharedPreferences(PREFS_NAME,0);
        SharedPreferences.Editor ed = settings.edit();
        ed.clear();
        ed.putString(region,sregion);
        ed.commit();
    }
    
    public String getRegion(){
            SharedPreferences settings= getSharedPreferences(PREFS_NAME,0);
            String myRegion = settings.getString(region,"us");
            String gRegion=myRegion;
            return gRegion;
        }
    
    public void changeLocale(String locale){
        try{
        String l= locale;
        if(l==("us")){
            this.isUs=true;
            Toast.makeText(this, "Us region P selected", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Prefs.this, dog.class);
            startActivity(intent);
        }
        if(l.equals("uk")){
            this.isUk=true;
            //Toast.makeText(this, "UK region selected", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Prefs.this, cat.class);
            startActivity(intent);
        }
                }catch (NullPointerException e){
            //what to do here?
            finish();
        }
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        SharedPreferences settings = getPreferences(0);
        SharedPreferences.Editor ed = settings.edit();
        ed.putString(region,region);
        ed.commit();
    
    }
    

    My submenu code in the dog class looks like this:

    public boolean onOptionsItemSelected(MenuItem item){
        Prefs pob = new Prefs();
        switch (item.getItemId()){
        //-------Options menu----------
        case R.id.about:
            //Toast.makeText(this, "About menu", Toast.LENGTH_SHORT).show();
            //showAbout();  
            return true;
        case R.id.locale:
            //Toast.makeText(this, "Locale menu", Toast.LENGTH_SHORT).show();
            return true;
    
        //-----Sub menu----------
    
                    case R.id.uk_item:
            Toast.makeText(this, "UK selected", Toast.LENGTH_SHORT).show();
            pob.editRegion("uk");
            pob.changeLocale("uk");
            finish();
            return true;
        case R.id.us_item:
            Toast.makeText(this, "US already selected", Toast.LENGTH_SHORT).show();
            pob.changeLocale("us");
            //finish();
            return true;
        default :
            return super.onOptionsItemSelected(item);
    
            }
    

    Thanks

  • Broo
    Broo almost 13 years
    Cool, thats got it, thanks Stephan. I still don't really understand the Context thing, other than its where stuff happens!
  • Prachi
    Prachi over 10 years
    Thanks a million @Stephan.
  • Muhammad Saqib
    Muhammad Saqib over 8 years
    Thanks for the information. Your sentence getSharedPreferences() can only be called after onCreate() has been called on an Activity. saved my lots of time.
  • Mansuu....
    Mansuu.... over 6 years
    I am getting SharedPreferences object in a helper class. I am passing context, but still it gives me NullPointerException sometimes.@Stephan
  • Mike Williamson
    Mike Williamson over 5 years
    What you write is true, @Imran, but it does not add value beyond what Stephan wrote 6 years earlier.
  • Peter Fortuin
    Peter Fortuin over 5 years
    Actually, I could call it in onCreate(), but not before it. So, it should be that "getSharedPreferences() can only be called in or after onCreate() has been called on an Activity. "