【问题标题】:SharedPreference Set<String> is resetting every time activity is recreated每次重新创建活动时,SharedPreference Set<String> 都会重置
【发布时间】:2013-12-23 08:16:11
【问题描述】:

为了便于阅读,我这里的代码将被简化。

获取Set并为其添加密码的方法:

public void addPass(String pass)
{
   // Get the current list.
   SharedPreferences sp = getSharedPreferences("passes", 0);
   SharedPreferences.Editor editor = getSharedPreferences("passes", 0).edit();
   Set<String> passes = sp.getStringSet("myStrings", new HashSet<String>());

   // Add the new value.
   passes.add(pass);

   // Save the list.
   editor.putStringSet("myStrings", passes);
   editor.commit();
}

public Set<String> getPasses()
{
    SharedPreferences sp = getSharedPreferences("passes", 0);
    return sp.getStringSet("myStrings", new HashSet<String>());
}

从集合中读取

Set<String> x = getPasses();
String[] passes = x.toArray(new String[0]); // convert the set to array

toast(Arrays.toString(passes)); // test what the set looks like

我将集合转换为数组,因为使用数组测试条件对我来说更容易。

添加到集合中

EditText password1 = new EditText(this);
String p1 = password1.getText().toString();

addPass(p1.trim()); // add it to the set
toast("Account successfully created.");

问题

当我第一次运行此代码时,我添加了三个字符串值:"a""b""c"(按此顺序)。

所有的值都被正确地添加到Set,并且从上面的这行代码中得到了确认:

toast(Arrays.toString(passes)); // test what the set looks like

在将"c" 添加到集合后,它输出了[b, c, a]

问题是当我关闭应用程序并重新打开它时,Set 只包含"a"。 我可以再次添加"b""c" 值,但循环将继续,Set保留在重新创建活动后添加到它的第一个值。

我已经解决了一段时间,无法修复它。如有必要,我可以提供有关如何以及何时使用此代码的更多详细信息。我希望我不需要,有人可以指出代码中的问题,如图所示。

【问题讨论】:

  • 每次添加 "b" 、 "c" 并重启应用都会出现这种情况?
  • 但是addPass(p1.trim()); 你只添加了一个值?
  • @sanjeevmk 是的。
  • @ρяσѕρєяK 该代码实际上在按钮侦听器中。对困惑感到抱歉。我添加了多个值。
  • @mikeyaworski : 问题是你每次在按钮点击 SharedPreferences 时都添加新的 HashSet 并使用相同的键 myStrings

标签: java android set sharedpreferences


【解决方案1】:

正在寻找相同问题的解决方案,解决方案将是

// Get the current list.
SharedPreferences sp = getSharedPreferences("passes", 0);
SharedPreferences.Editor editor = getSharedPreferences("passes", 0).edit();
Set<String> passes = sp.getStringSet("myStrings", new HashSet<String>());

//Make a copy, update it and save it
Set<String> newPasses = new HashSet<String>();
newPasses.add(pass);
newPasses.addAll(passes);
editor.putStringSet("myStrings", newPasses); editor.commit();

【讨论】:

    【解决方案2】:

    可能是您的问题源于使用 getStringSet(),请查看docs

    public abstract Set<String> getStringSet (String key, Set<String> defValues)
    

    从首选项中检索一组字符串值。

    请注意,您不能修改此调用返回的集合实例。如果您这样做,则无法保证存储数据的一致性,您也无法修改实例。

    【讨论】:

      【解决方案3】:

      基于这个 doc 和这个 SO Post 与你的问题完全相同,看来你应该创建一个新的副本返回的 HashSet 实例,你似乎至少从您在此处粘贴的代码中做到了这一点。也许还有其他东西被遗漏了。

      但是,请查看post 上的答案。那家伙所做的是:

      • 将第一个值作为字符串集添加到 SharedPreferences。
      • 要添加后续值,首先将现有首选项读入 new 字符串集。
      • 删除旧的字符串集键。
      • 修改新字符串集以添加要存储的新值。
      • 将新的字符串集添加到首选项中。

      虽然这是一种漫长而愚蠢的做事方式,但它似乎是最后的选择。因此,基本上,一次性存储您想要存储的所有值(而不是分期付款)。如果要添加新值,请删除旧键,使用旧值 + 新值创建新键,然后存储新键。

      希望对您有所帮助。

      【讨论】:

      • “看来你应该为返回的 HashSet 实例创建一个新副本,而且你似乎已经做到了”-> 他在哪里做到的? (也是@mikeyaworski)
      • @Mr_and_Mrs_D add_pass 中的这一行:Set&lt;String&gt; passes = sp.getStringSet("myStrings", new HashSet&lt;String&gt;());passes 是在那里创建的一个新实例。
      • 不——new HashSet&lt;String&gt;()) 只是默认值。这是您链接到的帖子的精确副本
      猜你喜欢
      • 1970-01-01
      • 2013-10-14
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      相关资源
      最近更新 更多