Intereting Posts
Набор инструментов для разработки Android Как переместить мою кнопку местоположения в google mapv2 в android? Веб-просмотр внутри списка: конфликты с событиями событий. Таким образом, невозможно отключить Zoom IN / OUT в android Использование putSerializable в Android Плагин Cordova для передачи ключевого кода события keyUp в приложение Не удалось загрузить lept из загрузчика findLibrary возвращается null? Пользовательское поведение режима контекстного действия Ошибка при установке приложения (INSTALL_FAILED_DEXOPT) Как я могу извлечь необработанную строку JSON из объекта OkHttp Response? JSONException: нет значения для XYZ при попытке getString («XYZ») Как обращаться с facebook как с подтверждением в андроид webview Как добавить шрифты в редактор Android Studio Экспорт пользовательского интерфейса App Inventor в Eclipse Сессионный файл cookie не истекает Когда Chrome Browser закрыт на смартфонах Преобразование битмапа в байтовый массив БЕЗ Bitmap.CompressFormat

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

благодаря

getSharedPreferences() может вызываться только после того, как onCreate() был вызван в Activity . Ваш класс onOptionsItemSelected() странно используется в 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() .

У меня было то же самое, и я не смог получить точный ответ на мою проблему, пока не пришел к ответу Стефана. Однако я хочу сделать его еще более ясным для следующего:

Я пытался получить доступ к общим предпочтениям за пределами действия, используя внешний класс, который не расширил класс 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); } 

getSharedPrefrences() нужен Context . Используйте следующее:

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