【问题标题】:Android: String set preference is not persistentAndroid:字符串集首选项不是持久的
【发布时间】:2013-05-25 02:08:13
【问题描述】:

我在存储字符串集首选项时遇到问题。我有这些实用的存储方法:

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 > 姜饼,使用 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. 我试图用 apply() 替换 commit() - 没有成功
  3. 当我在新 API 中使用旧 API 的代码时(我在两种方法中都注释了前 4 行),它可以完美运行,但效率不高

使用示例:

Editor e = mPref.edit();
PreferencesUtils.putStringSet(mPref, e, GlobalPreferences.INCLUDED_DIRECTORIES, dirs);
e.commit();

非常感谢您的帮助。

【问题讨论】:

标签: android string preferences


【解决方案1】:

这有大量的重复 - 我敢打赌你会这样做:

set = prefs.getStringSet("X", new HashSet<String>());
set.add("yada yada");
prefs.putStringSet("X", set);

简而言之,android 看到那个集合和里面的那个指的是同一个集合并且什么都不做。对吗?

见:Misbehavior when trying to store a string set using SharedPreferences

【讨论】:

    【解决方案2】:

    我的情况和你的很相似,唯一的区别是重启应用时,偏好包含A,B,C,但是当重新安装或重启手机时,B&C就没有了。

    我也尝试将 commit() 替换为 apply(),因为这篇文章建议 SharedPreferences not persistent ,但仍然无法正常工作。

    我通过在替换之前删除并提交首选项解决了这个问题:

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

    Ps:你可以在命令行输入adb pull /data/data/&lt;packagename&gt;/shared_prefs/xxxx.xml,看看commit()是否真的有效

    Pps:我认为这是 putStringSet 的一个错误......

    希望这会对你有所帮助;)

    【讨论】:

    • 我给你一个-1,因为你所要做的就是阅读javadoc for getStringSet()注意你不能修改这个调用返回的集合实例。如果您这样做,则无法保证所存储数据的一致性,也无法保证您修改实例的能力。 当您遇到问题时,解决方案不是黑客攻击 - 而是了解发生了什么。 为什么你必须删除集合并重新添加它?这对你来说真的有意义吗?
    • 编辑你的答案是正确的,将撤消我的投票
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2016-04-01
    • 2014-08-08
    • 1970-01-01
    • 2010-10-28
    • 2017-07-02
    相关资源
    最近更新 更多