【问题标题】:NullPointerException in SharedPreferences AndroidSharedPreferences Android 中的 NullPointerException
【发布时间】:2011-05-13 11:37:49
【问题描述】:

我第一次使用 sharedPreferences,我似乎无法克服这个错误。我有一个子菜单应该允许用户设置他们的区域。这应该会打开正确的区域活动,并在再次打开应用程序时存储和调用。 我一直在转圈很多次,所以有些代码会有点奇怪。我一直专注于从美国(默认)更改为英国。

在 DDMS 中我得到了这个:

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)

我的代码是这样的:

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

}

我在狗类中的子菜单代码如下:

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

        }

谢谢

【问题讨论】:

  • 代码中的哪一行产生了错误?

标签: android nullpointerexception sharedpreferences


【解决方案1】:

getSharedPreferences() 只能在 onCreate() 已在 Activity 上调用后调用。你的Prefs 类奇怪地用在onOptionsItemSelected() 中。通常,您不会自己实例化活动。如果您的 Prefs 类不是实际的 Activity 而是用于访问首选项的辅助类,请将 Context 对象传递给您的方法,如下所示:

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

并通过以下方式调用它:

pob.editRegion(this, "uk");

来自您的 onOptionsItemSelected() 方法。

【讨论】:

  • 酷,明白了,谢谢斯蒂芬。除了事情发生的地方,我仍然不太了解 Context 的事情!
  • 感谢一百万@Stephan。
  • 感谢您的信息。你的一句话getSharedPreferences() can only be called after onCreate() has been called on an Activity. 为我节省了很多时间。
  • 我在帮助类中获取 SharedPreferences 对象。我正在传递上下文,但有时它仍然给我 NullPointerException。@Stephan
  • 其实我可以在onCreate()中调用它,但不能在它之前调用。因此,应该是“getSharedPreferences() 只能在 Activity 上调用 onCreate() 时或之后调用。”
【解决方案2】:

我也遇到了同样的问题,但我无法得到准确的答案 我的问题,直到我得到斯蒂芬的答案。不过,我想让下一个更清楚:

我试图通过使用未扩展 Activity 类的外部类来访问活动之外的共享首选项。这导致了我同样的java.lang.NullPointerException

我的主要活动正在创建一个需要Context 才能访问共享首选项的对象:

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

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

您可以看到 MyClass 创建是在 onCreate 被调用之前完成的,这导致上下文“半生不熟”并抛出 java.lang.NullPointerException

为什么是“半生不熟”?在调试问题时,我在该行上设置了一个断点

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

在检查上下文参数时,我能够看到它的值(其中一些值)给出了参数已完全初始化的错误信念。

将 myClass 的初始化移到 onCreate 事件中解决了这个问题:

   ...
   ...
   MyClass myClass;

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

        myClass = new MyClass (this);
    }

【讨论】:

    【解决方案3】:

    getSharedPrefrences() 需要Context。像这样使用:

    SharedPreferences sp = mContext.getSharedPreferences("your_prefs", Activity.MODE_PRIVATE);
    

    【讨论】:

    • 你写的是真的,@Imran,但它并没有增加斯蒂芬 6 年前写的东西的价值。
    猜你喜欢
    • 2012-09-06
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    相关资源
    最近更新 更多