如何在 SharedPreferences 中存储键值对?
How to store key value pairs in SharedPreferences?
我正在开发一个随机生成密码的应用程序。我正在添加 "save" 功能,以便用户可以将他们的密码保存在 SharedPreferences
中。 (这不是您应该对密码执行的操作)
我有一个名为 PasswordActivity
的 activity,在那个 activity 中我显示了保存的密码。
我是这样保存密码的:我提示用户输入一个 name/key 的东西作为密码,以便 he/she 以后可以识别它。然后我在实用程序 class:
中使用以下方法将密钥和密码保存在 SharedPreferences 中
public static int savePassword (Context c, String passwordKey, String passwordValue) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
SharedPreferences.Editor editor = prefs.edit ();
boolean duplicateKey = !keys.add (passwordKey);
boolean duplicateValue = !values.add (passwordValue);
if (duplicateKey)
return KEY_DUPLICATE;
if (duplicateValue)
return VALUE_DUPLICATE;
editor.putStringSet (PASSWORD_KEYS, keys).
putStringSet (PASSWORD_VALUES, values).apply ();
return SUCCESS;
}
我写了另一个方法来获取密码和他们的名字。正如您可能已经猜到的那样,方法 return 是 HashMap<String, String>
。
public static HashMap<String, String> getPasswords (Context c) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
ArrayList<String> keysList = new ArrayList<> ();
ArrayList<String> valuesList = new ArrayList<> ();
for (String key : keys) {
keysList.add (key);
}
for (String value : values) {
valuesList.add (value);
}
HashMap<String, String> map = new HashMap<> ();
for (int i = 0 ; i < keys.size () ; i++) {
map.put (keysList.get (i), valuesList.get (i));
}
return map;
}
我承认代码很乱。我先把两个set里的东西都弄成ArrayList
s然后把array列表里的东西加到map和return.
呸!工作量很大!
现在当用户生成密码并保存时,两组包含正确的东西:(这些是假数据)
keys:
key1
values:
value1
一切都很好。但是当我生成另一个密码并保存时,两组就变得乱七八糟了:
keys:
key1
key2
values:
value2
value1
现在当我调用 getPasswords
方法时,它会 return
{key1, value2}, {key2, value1}
这是不正确的。查看文档后,我发现:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
我猜这是导致错误结果的原因。
所以我想知道是否有其他方法来存储这些密码及其名称?
我会推荐一个数据库,例如SQLCipher for Android,这样用户就可以为应用程序提供主密码,并且所有数据都加密存储在设备上。
但是,让我们假设,为了成功击退外星人入侵并防止无数人类被大规模屠杀,你必须使用SharedPreferences
来实现它。之后,你将需要与机智的同伴一起乘坐被征用的外星飞船,并成功将你的应用程序上传到其中一艘外星母舰的计算机系统中(幸运的是,它恰好是 运行 Android,因为 Android 在整个银河系拥有显着的市场份额)。
任一:
让每个键和值在 SharedPreferences
中成为单独的条目。毕竟,SharedPreferences
是 键值存储。为您的键和值使用专用的首选项文件(以免与您可能想要存储的任何其他内容发生冲突),然后您就知道所有的键都是来自用户的。
将 HashMap
编组为 JSON 或 XML 或其他内容并将其保存为字符串,根据需要解组。
由于您要存储多个名称和密码,我建议使用本地 SQLite 数据库。 SharedPreferences 适用于单个值,而不是值集。
如果您不想设置整个 SQLiteOpenHelper 和所有原始 SQL 代码,您可以看看一些 ORM 助手,例如 SugarOrm(我目前使用这个, 它非常容易设置和使用)
我正在开发一个随机生成密码的应用程序。我正在添加 "save" 功能,以便用户可以将他们的密码保存在 SharedPreferences
中。 (这不是您应该对密码执行的操作)
我有一个名为 PasswordActivity
的 activity,在那个 activity 中我显示了保存的密码。
我是这样保存密码的:我提示用户输入一个 name/key 的东西作为密码,以便 he/she 以后可以识别它。然后我在实用程序 class:
中使用以下方法将密钥和密码保存在 SharedPreferences 中public static int savePassword (Context c, String passwordKey, String passwordValue) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
SharedPreferences.Editor editor = prefs.edit ();
boolean duplicateKey = !keys.add (passwordKey);
boolean duplicateValue = !values.add (passwordValue);
if (duplicateKey)
return KEY_DUPLICATE;
if (duplicateValue)
return VALUE_DUPLICATE;
editor.putStringSet (PASSWORD_KEYS, keys).
putStringSet (PASSWORD_VALUES, values).apply ();
return SUCCESS;
}
我写了另一个方法来获取密码和他们的名字。正如您可能已经猜到的那样,方法 return 是 HashMap<String, String>
。
public static HashMap<String, String> getPasswords (Context c) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences (c);
Set<String> keys = prefs.getStringSet (PASSWORD_KEYS, new HashSet<String> ());
Set<String> values = prefs.getStringSet (PASSWORD_VALUES, new HashSet<String> ());
ArrayList<String> keysList = new ArrayList<> ();
ArrayList<String> valuesList = new ArrayList<> ();
for (String key : keys) {
keysList.add (key);
}
for (String value : values) {
valuesList.add (value);
}
HashMap<String, String> map = new HashMap<> ();
for (int i = 0 ; i < keys.size () ; i++) {
map.put (keysList.get (i), valuesList.get (i));
}
return map;
}
我承认代码很乱。我先把两个set里的东西都弄成ArrayList
s然后把array列表里的东西加到map和return.
呸!工作量很大!
现在当用户生成密码并保存时,两组包含正确的东西:(这些是假数据)
keys: key1 values: value1
一切都很好。但是当我生成另一个密码并保存时,两组就变得乱七八糟了:
keys: key1 key2 values: value2 value1
现在当我调用 getPasswords
方法时,它会 return
{key1, value2}, {key2, value1}
这是不正确的。查看文档后,我发现:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
我猜这是导致错误结果的原因。
所以我想知道是否有其他方法来存储这些密码及其名称?
我会推荐一个数据库,例如SQLCipher for Android,这样用户就可以为应用程序提供主密码,并且所有数据都加密存储在设备上。
但是,让我们假设,为了成功击退外星人入侵并防止无数人类被大规模屠杀,你必须使用SharedPreferences
来实现它。之后,你将需要与机智的同伴一起乘坐被征用的外星飞船,并成功将你的应用程序上传到其中一艘外星母舰的计算机系统中(幸运的是,它恰好是 运行 Android,因为 Android 在整个银河系拥有显着的市场份额)。
任一:
让每个键和值在
SharedPreferences
中成为单独的条目。毕竟,SharedPreferences
是 键值存储。为您的键和值使用专用的首选项文件(以免与您可能想要存储的任何其他内容发生冲突),然后您就知道所有的键都是来自用户的。将
HashMap
编组为 JSON 或 XML 或其他内容并将其保存为字符串,根据需要解组。
由于您要存储多个名称和密码,我建议使用本地 SQLite 数据库。 SharedPreferences 适用于单个值,而不是值集。
如果您不想设置整个 SQLiteOpenHelper 和所有原始 SQL 代码,您可以看看一些 ORM 助手,例如 SugarOrm(我目前使用这个, 它非常容易设置和使用)