单身共享偏好问题

时间:2014-10-09 06:50:07

标签: java android nullpointerexception singleton sharedpreferences

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

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

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

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

现在,我现在面临的问题是,有些时候,当我在活动A和D中调用它时,我在myPref.isAdmin()中得到空指针异常。但是大部分时间它的工作时间。

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

我再说一遍,我正在使用getApplicationContext()设置SharedPreference Context,因为它是单例,我在整个应用程序中使用它。

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

3 个答案:

答案 0 :(得分:1)

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

在MySharedPrefManager类中添加如下的getter方法:

public SharedPreferences getSharedPreference(){
    return SharedPref;
}

在您访问共享偏好内容的活动中,在onCreate或onResume中添加此内容,然后再使用内容:

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

这样你就可以避免NPE。

答案 1 :(得分: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);

答案 2 :(得分:0)

没必要,已经有单身人士了。你可以这样做:

PreferenceManager.getDefaultSharedPreferences(context);