安卓:String set preference不是持久化的

5

我遇到了存储字符串集合偏好的问题。我有以下用于存储的实用方法:

public static void putStringSet(SharedPreferences pref, Editor e, String key, Set<String> set)
{
    if (Utils.isApiLevelGreaterThanGingerbread())
    {
        // e.remove(key); // I tried to remove it here
        e.putStringSet(key, set);
    }
    else
    {
        // removes old occurences of key
        for (String k : pref.getAll().keySet())
        {
            if (k.startsWith(key))
            {
                e.remove(k);
            }
        }

        int i = 0;
        for (String value : set)
        {
            e.putString(key + i++, value);
        }
    }
}

public static Set<String> getStringSet(SharedPreferences pref, String key, Set<String> defaultValue)
{
    if (Utils.isApiLevelGreaterThanGingerbread())
    {
        return pref.getStringSet(key, defaultValue);
    }
    else
    {
        Set<String> set = new HashSet<String>();

        int i = 0;

        Set<String> keySet = pref.getAll().keySet();
        while (keySet.contains(key + i))
        {
            set.add(pref.getString(key + i, ""));
            i++;
        }

        if (set.isEmpty())
        {
            return defaultValue;
        }
        else
        {
            return set;
        }
    }
}

我使用这些方法来与GB向后兼容。但是我遇到了一个问题,即在API > gingerbread中使用putStringSet方法不是持久性的。它只在应用程序运行时是持久性的,但在重新启动后就会消失。我将描述以下步骤:
  1. 干净地安装应用程序-没有带有X键的首选项
  2. 我使用键为X的字符串集A-首选项包含A
  3. 我使用键为X的字符串集B-首选项包含B
  4. 关闭应用程序
  5. 重新启动应用程序-首选项包含A
  6. 我使用键为X的字符串集C-首选项包含C
  7. 关闭应用程序
  8. 重新启动应用程序-首选项包含A
所以只有第一个值是持久性的,我无法覆盖它。
其他注意事项:
  1. 这些方法只是替换了putStringSet和getStringSet。因此,我使用commit()……但在其他地方(见下面的示例)。
  2. 我尝试将commit()替换为apply()——但没有成功
  3. 当我在较新的API中使用旧API的代码时(我在两种方法中都注释了前4行),它可以完美地工作,但效率不高
使用示例:
Editor e = mPref.edit();
PreferencesUtils.putStringSet(mPref, e, GlobalPreferences.INCLUDED_DIRECTORIES, dirs);
e.commit();

非常感谢您的帮助。

你如何初始化目录? - Mr_and_Mrs_D
2个回答

8
这里有大量的重复内容 - 我打赌你也有:
set = prefs.getStringSet("X", new HashSet<String>());
set.add("yada yada");
prefs.putStringSet("X", set);

简而言之,Android认为set和内部的set是同一个set,因此不会执行任何操作。正确吗?
参见:Misbehavior when trying to store a string set using SharedPreferences

1

我的情况和你的非常相似,唯一的区别是当重新启动应用程序时,首选项包含A、B、C,但是当重新安装或重启手机时,B&C就会消失。

我也尝试将commit()替换为apply(),就像这篇文章SharedPreferences not persistent建议的那样,但仍然无法解决问题。

我通过删除&提交首选项来解决了这个问题,然后再进行替换:

editor.remove("StringSetKey");
editor.commit();

editor.putStringSet("StringSetKey", newSet);
editor.commit();

注:您可以在命令行中键入 adb pull /data/data/<packagename>/shared_prefs/xxxx.xml 查看 commit() 是否起作用。

另外,我认为这可能是 putStringSet 的一个 bug...

希望这能对您有所帮助 :)


我给你打负分是因为你只需要阅读javadoc for getStringSet()就可以了解到:请注意,您不能修改此调用返回的集合实例。如果您这样做,存储数据的一致性将无法保证,您也无法修改该实例。当您面临问题时,解决方案不是使用hack,而是理解发生了什么。为什么您必须删除集合并重新添加它?这对您真的有意义吗? - Mr_and_Mrs_D
编辑你的回答以纠正并撤销我的投票 - Mr_and_Mrs_D

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