2

Это пример моего приложения.singleton shared preferences issue

Я создал одноэлементные общие предпочтения, которые использовали пользовательский Общий класс менеджера предпочтения редактировать общие значения данных предпочтения:

public class MySharedPrefManager { 
    private static MySharedPrefManager instance= null; 
    private static SharedPreferences SharedPref; 
    private static Editor SPEditor; 

    private MySharedPrefManager() { 
    } 
    public static MySharedPrefManager getInstance(){ 
     if(instance==null) 
      instance= new MySharedPrefManager(); 
     return instance; 
    } 

    public void setSharedPreferences(Context context){ 
     SharedPref= context.getSharedPreferences("MySharedPref", Context.MODE_PRIVATE); 
     SPEditor= SPEditor.edit(); 
    } 
    public void setAdmin(boolean pAdmin) { 
     SharedPrefManager.editBoolean("isAdmin", pAdmin, SPEditor); 
    } 
    public boolean isAdmin() {   
     return SharedPref.getBoolean("isAdmin", false); 
    } 
} 

Общий менеджер предпочтения:

public class SharedPrefManager { 
    public static void editString(String key, String value, Editor pEditor){ 
     pEditor.putString(key, value); 
     pEditor.commit(); 
    } 
    public static void editBoolean(String key, boolean value, Editor pEditor){ 
     pEditor.putBoolean(key, value); 
     pEditor.commit(); 
    } 

У меня есть много мероприятий который идет как действия: A-> B-> C-> D-> E-> F-> G

Активность А, которая является начальным действием, я получаю экземпляр MySharedPrefManager и d установить SharedPreferences также:

public class ActivityA extends Activity{ 
    private MySharedPrefManager myPref; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.initialization); 

     myPref= MySharedPrefManager.getInstance(); 
     // I am setting the SharedPreference Context with getApplicationContext(), 
     // as it is singleton, and I am using it through out my application 
     myPref.setSharedPreferences(getApplicationContext()); 
     // other stuff... 
    } 

    private void changeData(){ 
     myPref.setAdmin(true); 
    } 

    private void check(){ 
     if(myPref.isAdmin()){ 
      // do- something 
     } 
    } 
} 

ActivityD:

public class ActivityD extends Activity{ 

    private MySharedPrefManager myPref; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.initialization); 
     // Here i called only the instance not the setSharedPreferences. 
     myPref= MySharedPrefManager.getInstance(); 

     // other stuff... 
    } 
    private void changeData(){ 
     myPref.setAdmin(true); 
    } 
    private void check(){ 
     if(myPref.isAdmin()){ 
      // do- something 
     } 
    } 
} 

Теперь вопрос я столкнулся сейчас является то, что несколько раз я получаю исключения нулевого указателя в myPref.isAdmin() когда Я называю это как в действии А, так и в D. Но большую часть времени он работает.

Также необходимо установить SharedPreferences (вызов метода setSharedPreferences()) в каждом из действий? Я не чувствую, что нужно установить, так как это одноэлементный класс.

Повторяю, я устанавливаю контекст SharedPreference с getApplicationContext(), поскольку он является одиночным, и я использую его через свое приложение.

Отредактировано: Есть 3-4 общих предпочтения, которые я использую с той же структурой .. С аналогичной проблемой. Использование этого PreferenceManager.getDefaultSharedPreferences (контекст);, я смогу использовать только ОДИН SharedPreference, который является SharedPreference по умолчанию.

+1

попробуйте 'PreferenceManager.getDefaultSharedPreferences (контекст);' – Pr38y

ответ

1

Перед использованием элементов данных или содержимое MySharedPrefManager, проверьте нуль-проверки.

В классе MySharedPrefManager добавить геттер, как это:

public SharedPreferences getSharedPreference(){ 
    return SharedPref; 
} 

В деятельности, где вы доступ к общим содержанием предпочтений, в OnCreate или onResume добавить это перед использованием содержимого:

myPref= MySharedPrefManager.getInstance(); 
if(myPref.getSharedPreference()==null){ 
    myPref.setSharedPreferences(getApplicationContext()); 
} 

Таким образом, вы сможете избежать NPE.

0

Не нужно, там уже есть синглтон. Вы можете сделать:

PreferenceManager.getDefaultSharedPreferences(context); 
+0

, пожалуйста, просмотрите отредактированную часть – OnePunchMan

1

Исключение нулевого указателя, вероятно, вызвано тем, что ваш синглтон не инициализирован. Я полагаю, это происходит, когда вы вращаете устройство?

Ожидается следующее: В действии A вы делаете getInstance() и setSharedPreferences(). В действии B вы делаете только getInstance() и ожидаете получить тот же экземпляр, который был создан в A.Но если вы вращаете устройство в то время как в B, то B воссоздается, что делает getInstance(), но на этот раз он должен сам создать свой экземпляр. И на этот раз инициализация не будет выполнена с setSharedPreferences().

Советую сделать ваш prefs класс более простым. Убедитесь, что вы инициализируетесь при построении. То есть не выделяйте getInstance() и setSharedPreferences(). Сделайте что-то вроде этого:

public class MySharedPrefManager { 
    private SharedPreferences sharedPref; 

    private MySharedPrefManager(Context context) { 
     sharedPref = PreferenceManager.getDefaultSharedPreferences(context); 
    } 

    public static MySharedPrefManager from(Context context) { 
     return new MySharedPrefManager(context); 
    } 

    public void setAdmin(boolean pAdmin) { 
     sharedPref.edit().putBoolean("isAdmin", pAdmin).apply(); 
    } 

    public boolean isAdmin() { 
     return sharedPref.getBoolean("isAdmin", false); 
    } 
} 

И использовать его как это, когда вам нужно сделать несколько настроек:

MySharedPrefManager prefs = MySharedPrefManager.from(this); 
prefs.setAdmin(true); 
prefs.setSomethingElse(); 
boolean isFoo = prefs.isFoo(); 

Или использовать сокращенный вариант, если требуется только один параметр:

MySharedPrefManager.from(this).setAdmin(true); 
Смежные вопросы