web-dev-qa-db-ja.com

SharedPreferencesのNullPointerException Android

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

}

Dogクラスのサブメニューコードは次のようになります。

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

        }

ありがとう

12
Broo

getSharedPreferences()は、onCreate()Activityで呼び出された後にのみ呼び出すことができます。 PrefsクラスがonOptionsItemSelected()で奇妙に使用されています。一般に、アクティビティを自分でインスタンス化することはありません。 Prefsクラスが実際のアクティビティではなく、設定にアクセスするためのヘルパークラスである場合は、次のように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()メソッドから。

39
Stephan

私も同じことをしていて、ステファンの答えにたどり着くまで、問題に対する正確な答えを得ることができませんでした。ただし、次の予定については、さらに明確にしたいと思います。

Activityクラスを拡張していない外部クラスを使用して、アクティビティの外部で共有設定にアクセスしようとしていました。これは私に同じJava.lang.NullPointerExceptionを引き起こしました。

私の主な活動は、共有設定にアクセスするためにContextを必要とするオブジェクトを作成することでした。

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

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

OnCreateが呼び出される前にMyClassの作成が行われていることがわかるように、これによりコンテキストが「Half-Baked」になり、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);
    }
7
Tal Tikotzki

getSharedPrefrences() need Context。このように使用します:

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