Android中共享首选项的奇怪问题

时间:2011-09-01 10:19:18

标签: android sharedpreferences

我正在尝试使用共享首选项来存储我的应用程序设置,但即使我试图最好地复制教程,因为我仍然无法使其工作。以下是我班级的部分内容:

public class ActivitySettings extends PreferenceActivity {

@SuppressWarnings("unused")
private static String TAG = "ActivitySettings";

private static final String PREFS_NAME = "preferences";

private static final String DISABLE_CHECK = "disableCheck";
private static final String ALWAYS_CONFIRM = "alwaysConfirm";
private static final String NEVER_CONFIRM = "neverConfirm";
private static final String SHOW_NOTIFICATION = "showNotification";
private static final String SHOW_ON_BOOT = "showOnBoot";
private static final String HIDE_ICON = "hideIcon";
private static final String LOGGING = "logging";

private Context context = this;

private CheckBoxPreference disableCodeCheck;
private CheckBoxPreference alwaysAskForConf;
private CheckBoxPreference neverAskForConf;
private CheckBoxPreference showNotif;
private CheckBoxPreference showAtBoot;
private CheckBoxPreference hideIcon;
private Preference exportData;
private Preference importData;
private Preference cleanUp;
private Preference reset;
private CheckBoxPreference logging;

private boolean isDisableCodeCheck;
private boolean isAlwaysAskForConf;
private boolean isNeverAskForConf;
private boolean isShowNotif;
private boolean isShowAtBoot;
private boolean isHideIcon;
private boolean isLogging;

private void loadPreferences() {
    SharedPreferences prefs = getSharedPreferences(PREFS_NAME, 0);

    isDisableCodeCheck = prefs.getBoolean(DISABLE_CHECK, false);
    isAlwaysAskForConf = prefs.getBoolean(ALWAYS_CONFIRM, false);
    isNeverAskForConf = prefs.getBoolean(NEVER_CONFIRM, false);
    isShowNotif = prefs.getBoolean(SHOW_NOTIFICATION, false);
    isShowAtBoot = prefs.getBoolean(SHOW_ON_BOOT, false);
    isHideIcon = prefs.getBoolean(HIDE_ICON, false);
    isLogging = prefs.getBoolean(LOGGING, false);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    addPreferencesFromResource(R.xml.settings);

    disableCodeCheck = (CheckBoxPreference) findPreference("disable_code_check");
    alwaysAskForConf = (CheckBoxPreference) findPreference("always_ask_for_conf");
    neverAskForConf = (CheckBoxPreference) findPreference("never_ask_for_conf");
    showNotif = (CheckBoxPreference) findPreference("show_notif");
    showAtBoot = (CheckBoxPreference) findPreference("show_at_boot");
    hideIcon = (CheckBoxPreference) findPreference("hide_icon");
    exportData = findPreference("exp");
    importData = findPreference("imp");
    cleanUp = findPreference("clean_up");
    reset = findPreference("reset");
    logging = (CheckBoxPreference) findPreference("logging");

    loadPreferences();

    //here are also booleans modified

@Override
protected void onStop() {
    super.onStop();
    savePreferences();
}

private void savePreferences() {
    SharedPreferences prefs = getSharedPreferences(PREFS_NAME, 0);

    prefs.edit().putBoolean(DISABLE_CHECK, isDisableCodeCheck);
    prefs.edit().putBoolean(ALWAYS_CONFIRM, isAlwaysAskForConf);
    prefs.edit().putBoolean(NEVER_CONFIRM, isNeverAskForConf);
    prefs.edit().putBoolean(SHOW_NOTIFICATION, isShowNotif);
    prefs.edit().putBoolean(SHOW_ON_BOOT, isShowAtBoot);
    prefs.edit().putBoolean(HIDE_ICON, isHideIcon);
    prefs.edit().putBoolean(LOGGING, isLogging);

    prefs.edit().commit();
}

}

以下是发生的事情:

  1. 在shared_prefs中创建了两个文件:preferences.xml和packagename_preferences.xml。不知道原因,提供了PREFS_NAME。

  2. 加载设置在onCreate方法中完成,在onStop中保存和提交

  3. 使用adb shell和cat我在应用程序运行时查看文件,这是场景:

    • 我打开设置并打勾,并使用正确的值
    • 创建packagename_preferences.xml
    • 我按下并创建第二个文件 - preferences.xml,如下所示: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map />
    • 当我再次打开设置时,一切看起来像第一次运行,packagename_preferences.xml中的值更改为默认值(?)
  4. 我知道PreferenceActivity有内置机制,但我不想使用它,因为我需要访问其他活动中的其他设置。


  5. 修改


    我创建了这样的应用程序:

    package pl.test;
    
    import android.app.Activity;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    
    public class TestActivity extends Activity {
    String s = "0";
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        SharedPreferences sp = getSharedPreferences("pref", 0);  
        s = sp.getString("setting2", "1");
        s = "5";
    }
    
    @Override
    public void onStop() {
        super.onStop();
        SharedPreferences sp = getSharedPreferences("pref", 0);
        sp.edit().putString("setting2", s);
        sp.edit().commit();
    }
    

    }

    它不起作用它只是不将字符串保存到pref.xml。有什么问题!?

2 个答案:

答案 0 :(得分:3)

您的问题是每次调用sp.edit()时都会生成一个新的Editor对象。所以你的调用sp.edit()。commit()正在创建一个没有提交更改的新编辑器。试试这个:

private void savePreferences() {
    SharedPreferences prefs = getSharedPreferences(PREFS_NAME, 0);
    SharedPreferences.Editor editor = prefs.edit(); 
    editor.putBoolean(DISABLE_CHECK, isDisableCodeCheck);
    editor.putBoolean(ALWAYS_CONFIRM, isAlwaysAskForConf);
    editor.putBoolean(NEVER_CONFIRM, isNeverAskForConf);
    editor.putBoolean(SHOW_NOTIFICATION, isShowNotif);
    editor.putBoolean(SHOW_ON_BOOT, isShowAtBoot);
    editor.putBoolean(HIDE_ICON, isHideIcon);
    editor.putBoolean(LOGGING, isLogging);
    editor.commit();
}

或者,编辑器方法设计为链接,因此这也可以工作:

private void savePreferences() {
    SharedPreferences prefs = getSharedPreferences(PREFS_NAME, 0)
        prefs.edit().putBoolean(DISABLE_CHECK, isDisableCodeCheck)
        .putBoolean(ALWAYS_CONFIRM, isAlwaysAskForConf)
        .putBoolean(NEVER_CONFIRM, isNeverAskForConf)
        .putBoolean(SHOW_NOTIFICATION, isShowNotif)
        .putBoolean(SHOW_ON_BOOT, isShowAtBoot)
        .putBoolean(HIDE_ICON, isHideIcon)
        .putBoolean(LOGGING, isLogging)
        .commit();
}

您的测试代码中存在同样的问题,可以像以下一样修复:

@Override
public void onStop() {
    super.onStop();
    SharedPreferences sp = getSharedPreferences("pref", 0);
    sp.edit().putString("setting2", s).commit();
}

答案 1 :(得分:1)

在阅读第一个应用程序共享的世界可读数据时,我们应该

替换

getSharedPreferences("PREF_NAME", Context.MODE_PRIVATE);

getSharedPreferences("PREF_NAME", Context.MODE_MULTI_PROCESS);

在第二个应用中获取第二个应用中的更新值。