【问题标题】:SharedPreferences putStringSet doesn't work [duplicate]SharedPreferences putStringSet 不起作用[重复]
【发布时间】:2014-02-19 04:57:14
【问题描述】:

我需要将 Set 放入 SharedPreference,但我有问题。

当我点击按钮时,我会从 SharedPreference 中获取 Set 并将数据添加到 Set 然后放回 SharedPreference,但是当我销毁项目并再次打开它时,sharedPreference 只能在 Set 中获取一个字符串

SharedPreferences s = getSharedPreferences("db", 0);
Log.i("chauster", "1.set = "+s.getStringSet("set", new HashSet<String>()));

Button btn = (Button)findViewById(R.id.button1);
btn.setOnClickListener(new Button.OnClickListener() {

    @Override
    public void onClick(View v) {
        SharedPreferences ss = getSharedPreferences("db", 0);
        Set<String> hs = ss.getStringSet("set", new HashSet<String>());
        hs.add(String.valueOf(hs.size()+1));
        Editor edit = ss.edit();
        edit.putStringSet("set", hs);
        edit.commit();
        SharedPreferences sss = getSharedPreferences("db", 0);
        Log.i("chauster", "2.set = "+sss.getStringSet("set",
                new HashSet<String>()));
    }
});

当我首先安装项目时,我点击按钮 4 次,logcat 打印它

1.set = []
2.set = [1]
2.set = [2, 1]
2.set = [3, 2, 1]
2.set = [3, 2, 1, 4]

将字符串放入sharedPreference Set看起来很成功,但是当我销毁应用程序并再次打开它时,logcat会打印它

1.set = [1]

表示sharedPreference的Set中只有一个字符串,不知道怎么回事? 请帮我。谢谢~

【问题讨论】:

  • 也许你应该接受我的回答,因为接受的是错误的

标签: android sharedpreferences


【解决方案1】:

您陷入了编辑从 getStringSet() 获得的值的常见陷阱。这是禁止的in the docs

你应该:

SharedPreferences ss = getSharedPreferences("db", 0);
Set<String> hs = ss.getStringSet("set", new HashSet<String>());
Set<String> in = new HashSet<String>(hs);
in.add(String.valueOf(hs.size()+1));
ss.edit().putStringSet("set", in).commit(); // brevity
// SharedPreferences sss = getSharedPreferences("db", 0); // not needed
Log.i("chauster", "2.set = "+ ss.getStringSet("set", new HashSet<String>()));

半生不熟的解释见:Misbehavior when trying to store a string set using SharedPreferences

【讨论】:

  • 这是正确答案
  • 感谢您发布此内容并附上说明!
  • 糟糕的 SDK 设计。如果需要,实现应该返回一个不可变集 (Collections.unmodifiableSet())。
  • 我当时发布了一个问题 @Jeffrey - 现在找不到
  • 这是正确答案。我浪费了几个小时来寻找问题。谢谢!
【解决方案2】:

在 putStringSet 之前使用 edit.clear()

SharedPreferences ss = getSharedPreferences("db", 0);
Set<String> hs = ss.getStringSet("set", new HashSet<String>());
hs.add(String.valueOf(hs.size()+1));
Editor edit = ss.edit();
edit.clear();
edit.putStringSet("set", hs);
edit.commit();

【讨论】:

  • 为什么不清除就不行...是同一个键有问题吗?
  • 这不是解决方案... clear() 删除所有首选项!
  • 这将清除 所有 首选项,改为通过键删除 - edit.remove('set')。但是可以通过从 pref 返回的集合创建一个新集合来避免这种情况,例如 Set&lt;String&gt; new = new HashSet&lt;&gt;(ss.getStringSet('set', new HashSet&lt;String&gt;()));
  • 不起作用...
【解决方案3】:

RemoveSharedPreferencesHashSet 的键,commit 然后添加新值。

SharedPreferences ss;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_third);
    ss = getSharedPreferences("db", 0);
    fun();
}

void fun() {
    Log.i("chauster", "1.set = "+ss.getStringSet("set", new HashSet<String>()));

    Button btn = (Button)findViewById(R.id.btn);
    btn.setOnClickListener(new Button.OnClickListener() {

        @Override
        public void onClick(View v) {
            Set<String> hs = ss.getStringSet("set", new HashSet<String>());
            hs.add(String.valueOf(hs.size()+1));
            Log.i(TAG, "list: " + hs.toString());
            Editor edit = ss.edit();
            edit.remove("set");
            edit.commit();
            edit.putStringSet("set", hs);
            Log.i(TAG, "saved: " + edit.commit());

            Log.i("chauster", "2.set = "+ss.getStringSet("set", new HashSet<String>()));
        }
    });
}

【讨论】:

    【解决方案4】:

    伙计们,出于历史原因,我将其保留在这里。不要使用这种方法! (它有什么用?它显示了糟糕的代码出现的程度:API 的行为违反直觉,有一个问题,开发人员试图解决问题。出现了错误的代码。后来,问题得到了官方文档,并且一个不同的建议了解决方法,但错误的代码会被共享。)


    尝试将 SharedPreferences 存储到静态变量,而不是每次都调用 getSharedPreferences。这听起来很糟糕,但这对我有用一次。

    public class Prefs {
        // this singleton is a workaround for an Android bug:
        // two SharedPreferences objects do not see changes in each other.
        private static SharedPreferences theSingletone;
        public static SharedPreferences get(Activity from) {
            //PreferenceManager.getDefaultSharedPreferences(getContext());
            if (theSingletone == null) {
                theSingletone = from.getApplicationContext().getSharedPreferences("prefs", Context.MODE_PRIVATE);
            }
            return theSingletone;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-10-10
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 2016-10-11
      • 2015-02-09
      • 2012-01-07
      • 2014-02-13
      相关资源
      最近更新 更多