单例共享偏好设置问题

3

这只是我应用程序的一个示例。

我创建了一个单例共享偏好设置,使用自定义的Shared preference管理器类来编辑共享偏好数据值:

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

A活动是启动活动,我获取MySharedPrefManager实例并设置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
        }
    }
}

目前我面临的问题是,在 A 和 D 两个活动中调用 myPref.isAdmin() 方法时,有时会出现 Null pointer 异常,但大多数情况下它可以正常工作。

此外,我需要在每个活动中设置 SharedPreferences (调用 setSharedPreferences() 方法) 吗?我认为不需要,因为它是单例模式。

我想强调一下,我正在使用 getApplicationContext() 设置 SharedPreference Context,并将其在整个应用程序中使用,因为它是单例的。

编辑: 我正在使用 3-4 个具有相同结构的 shared preferences,遇到类似的问题。使用 PreferenceManager.getDefaultSharedPreferences(context);,我只能使用默认的 SharedPreference。


1
尝试使用 PreferenceManager.getDefaultSharedPreferences(context); - Pr38y
3个回答

2
空指针异常可能是由于您的单例未初始化造成的。我猜想这是在旋转设备时发生的?
我认为以下情况会发生:在Activity A中,您执行getInstance()和setSharedPreferences()。在Activity B中,您只执行getInstance()并期望得到与A中创建的相同实例。但是,如果您在B中旋转设备,则B将被重新创建,它将执行getInstance(),但这次它必须自己创建其实例。而这一次它将不会使用setSharedPreferences()进行初始化。
我的建议是使您的prefs类更简单。确保在构造时进行初始化。即不要将getInstance()和setSharedPreferences()分开。像这样做:
```java public class MyPrefs { private static MyPrefs instance = new MyPrefs(); private SharedPreferences prefs;
private MyPrefs() { prefs = PreferenceManager.getDefaultSharedPreferences(context); }
public static MyPrefs getInstance() { return instance; }
public SharedPreferences getPrefs() { return prefs; } } ```
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);

1

在使用MySharedPrefManager的数据成员或内容之前,请进行空值检查。

在MySharedPrefManager类中添加一个像这样的getter方法:

public SharedPreferences getSharedPreference(){
    return SharedPref;
}

在访问共享首选项内容的活动中,在onCreate或onResume中使用以下代码,然后再使用内容:
myPref= MySharedPrefManager.getInstance();
if(myPref.getSharedPreference()==null){
    myPref.setSharedPreferences(getApplicationContext());
}

这样你就能避免NPE错误。


0

不需要,已经有单例了。你可以这样做:

PreferenceManager.getDefaultSharedPreferences(context);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接