NullPointerException в SharedPreferences 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();
}
Мой код подменю в классе собаки выглядит следующим образом:
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);
}
Спасибо
Ответы
Ответ 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()
.
Ответ 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, это привело к тому, что контекст был "Half-Baked" и выбрал java.lang.NullPointerException
.
Почему "Half-Baked"? При отладке проблемы у меня была точка останова на линии
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);