【问题标题】:singleton shared preferences issue单身共享偏好问题
【发布时间】:2014-10-09 06:50:07
【问题描述】:

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

我创建了一个单例共享首选项,它使用自定义共享首选项管理器类来编辑共享首选项数据值:

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

Activity 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
        }
    }
}

活动D:

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

现在,我现在面临的问题是,当我在 Activity A 和 D 中调用它时,有时我会在 myPref.isAdmin() 中得到 Null 指针异常。但大多数它的工作时间。

我还需要在每个活动中设置SharedPreferences(调用setSharedPreferences()方法)吗?我觉得不需要设置,因为它是单例类。 p>

重复一遍,我正在使用 getApplicationContext() 设置 SharedPreference 上下文,因为它是单例的,并且我在整个应用程序中都在使用它。

已编辑:我正在使用具有相同结构的 3-4 个共享首选项。有类似的问题。使用这个 PreferenceManager.getDefaultSharedPreferences(context);,我将只能使用一个 SharedPreference,它是默认的 SharedPreference。

【问题讨论】:

  • 试试PreferenceManager.getDefaultSharedPreferences(context);

标签: java android nullpointerexception singleton sharedpreferences


【解决方案1】:

空指针异常可能是因为你的单例没有被初始化。我想这会在您旋转设备时发生?

我预计会发生以下情况:在活动 A 中,您执行 getInstance()setSharedPreferences()。在活动 B 中,您只执行 getInstance() 并期望获得在 A 中创建的相同实例。但是如果您在 B 中旋转设备,则重新创建 B 执行 getInstance(),但这次它必须创建它的实例本身。而这一次它不会使用setSharedPreferences() 进行初始化。

我的建议是让你的 prefs 类更简单。确保您在构造上进行初始化。 IE。不要分离出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);

【讨论】:

    【解决方案2】:

    在使用 MySharedPrefManager 的数据成员或内容之前,请检查 null 检查。

    在 MySharedPrefManager 类中添加一个 getter 方法,如下所示:

    public SharedPreferences getSharedPreference(){
        return SharedPref;
    }
    

    在您访问共享首选项内容的活动中,在 onCreate 或 onResume 中添加以下内容,然后再使用内容:

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

    这样你就可以避免 NPE。

    【讨论】:

      【解决方案3】:

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

      PreferenceManager.getDefaultSharedPreferences(context);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-11
        • 2016-06-13
        • 1970-01-01
        • 2021-12-09
        • 2015-11-07
        相关资源
        最近更新 更多