【发布时间】:2011-12-18 04:17:53
【问题描述】:
如何在 Android 中将 HashMap 对象 保存到 Shared Preferences 中?
【问题讨论】:
如何在 Android 中将 HashMap 对象 保存到 Shared Preferences 中?
【问题讨论】:
我使用Gson将HashMap转换为String,然后保存到SharedPrefs
private void hashmaptest()
{
//create test hashmap
HashMap<String, String> testHashMap = new HashMap<String, String>();
testHashMap.put("key1", "value1");
testHashMap.put("key2", "value2");
//convert to string using gson
Gson gson = new Gson();
String hashMapString = gson.toJson(testHashMap);
//save in shared prefs
SharedPreferences prefs = getSharedPreferences("test", MODE_PRIVATE);
prefs.edit().putString("hashString", hashMapString).apply();
//get from shared prefs
String storedHashMapString = prefs.getString("hashString", "oopsDintWork");
java.lang.reflect.Type type = new TypeToken<HashMap<String, String>>(){}.getType();
HashMap<String, String> testHashMap2 = gson.fromJson(storedHashMapString, type);
//use values
String toastString = testHashMap2.get("key1") + " | " + testHashMap2.get("key2");
Toast.makeText(this, toastString, Toast.LENGTH_LONG).show();
}
【讨论】:
我不建议将复杂对象写入 SharedPreference。相反,我会使用ObjectOutputStream 将其写入内部存储器。
File file = new File(getDir("data", MODE_PRIVATE), "map");
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(map);
outputStream.flush();
outputStream.close();
【讨论】:
private void saveMap(Map<String,Boolean> inputMap) {
SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
if (pSharedPref != null){
JSONObject jsonObject = new JSONObject(inputMap);
String jsonString = jsonObject.toString();
pSharedPref.edit()
.remove("My_map")
.putString("My_map", jsonString)
.apply();
}
}
private Map<String,Boolean> loadMap() {
Map<String,Boolean> outputMap = new HashMap<>();
SharedPreferences pSharedPref = getApplicationContext().getSharedPreferences("MyVariables", Context.MODE_PRIVATE);
try {
if (pSharedPref != null) {
String jsonString = pSharedPref.getString("My_map", (new JSONObject()).toString());
if (jsonString != null) {
JSONObject jsonObject = new JSONObject(jsonString);
Iterator<String> keysItr = jsonObject.keys();
while (keysItr.hasNext()) {
String key = keysItr.next();
Boolean value = jsonObject.getBoolean(key);
outputMap.put(key, value);
}
}
}
} catch (JSONException e){
e.printStackTrace();
}
return outputMap;
}
【讨论】:
getApplicationContext?
getString() 的奇怪复杂的默认值有什么意义?一个简单的 null 或空字符串不是也能正常工作吗?
Map<String, String> aMap = new HashMap<String, String>();
aMap.put("key1", "val1");
aMap.put("key2", "val2");
aMap.put("Key3", "val3");
SharedPreferences keyValues = getContext().getSharedPreferences("Your_Shared_Prefs"), Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();
for (String s : aMap.keySet()) {
keyValuesEditor.putString(s, aMap.get(s));
}
keyValuesEditor.commit();
【讨论】:
作为 Vinoj John Hosan 答案的衍生,我修改了答案以允许更通用的插入,基于数据的键,而不是像 "My_map" 这样的单个键。
在我的实现中,MyApp 是我的 Application 覆盖类,MyApp.getInstance() 用于返回 context。
public static final String USERDATA = "MyVariables";
private static void saveMap(String key, Map<String,String> inputMap){
SharedPreferences pSharedPref = MyApp.getInstance().getSharedPreferences(USERDATA, Context.MODE_PRIVATE);
if (pSharedPref != null){
JSONObject jsonObject = new JSONObject(inputMap);
String jsonString = jsonObject.toString();
SharedPreferences.Editor editor = pSharedPref.edit();
editor.remove(key).commit();
editor.putString(key, jsonString);
editor.commit();
}
}
private static Map<String,String> loadMap(String key){
Map<String,String> outputMap = new HashMap<String,String>();
SharedPreferences pSharedPref = MyApp.getInstance().getSharedPreferences(USERDATA, Context.MODE_PRIVATE);
try{
if (pSharedPref != null){
String jsonString = pSharedPref.getString(key, (new JSONObject()).toString());
JSONObject jsonObject = new JSONObject(jsonString);
Iterator<String> keysItr = jsonObject.keys();
while(keysItr.hasNext()) {
String k = keysItr.next();
String v = (String) jsonObject.get(k);
outputMap.put(k,v);
}
}
}catch(Exception e){
e.printStackTrace();
}
return outputMap;
}
【讨论】:
Context 实例一样执行此操作。查看其他 SO 问题:Is it possible to get application's context in an Android Library Project?
地图 -> 字符串
val jsonString: String = Gson().toJson(map)
preferences.edit().putString("KEY_MAP_SAVE", jsonString).apply()
字符串 -> 地图
val jsonString: String = preferences.getString("KEY_MAP_SAVE", JSONObject().toString())
val listType = object : TypeToken<Map<String, String>>() {}.type
return Gson().fromJson(jsonString, listType)
【讨论】:
您可以尝试使用 JSON。
为了节省
try {
HashMap<Integer, String> hash = new HashMap<>();
JSONArray arr = new JSONArray();
for(Integer index : hash.keySet()) {
JSONObject json = new JSONObject();
json.put("id", index);
json.put("name", hash.get(index));
arr.put(json);
}
getSharedPreferences(INSERT_YOUR_PREF).edit().putString("savedData", arr.toString()).apply();
} catch (JSONException exception) {
// Do something with exception
}
为了得到
try {
String data = getSharedPreferences(INSERT_YOUR_PREF).getString("savedData");
HashMap<Integer, String> hash = new HashMap<>();
JSONArray arr = new JSONArray(data);
for(int i = 0; i < arr.length(); i++) {
JSONObject json = arr.getJSONObject(i);
hash.put(json.getInt("id"), json.getString("name"));
}
} catch (Exception e) {
e.printStackTrace();
}
【讨论】:
您可以在专用的共享首选项文件中使用它(来源:https://developer.android.com/reference/android/content/SharedPreferences.html):
全部获取
在 API 级别 1 中添加了 Map getAll () 从以下位置检索所有值 偏好。
注意,不能修改此方法返回的集合, 或更改其任何内容。您存储的数据的一致性是 不保证会这样做。
返回 Map 返回包含对列表的映射 表示偏好的键/值。
【讨论】:
String converted = new Gson().toJson(map);
SharedPreferences sharedPreferences = getSharedPreferences("sharepref",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("yourkey",converted).commit();
【讨论】:
对于狭窄的用例,当您的地图只有不超过几十个元素时,您可以利用 SharedPreferences 的工作方式与地图非常相似的事实,只需将每个条目存储在自己的键下:
Map<String, String> map = new HashMap<String, String>();
map.put("color", "red");
map.put("type", "fruit");
map.put("name", "Dinsdale");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// OR use a specific pref name
// context.getSharedPreferences("myMegaMap");
for (Map.Entry<String, String> entry : map.entrySet()) {
prefs.edit().putString(entry.getKey(), entry.getValue());
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// OR use a specific pref name
// context.getSharedPreferences("myMegaMap");
prefs.getString("color", "pampa");
如果您使用自定义首选项名称(即context.getSharedPreferences("myMegaMap")),您还可以使用prefs.getAll() 获取所有键
您的值可以是 SharedPreferences 支持的任何类型:
String、int、long、float、boolean。
【讨论】:
使用File Stream
fun saveMap(inputMap: Map<Any, Any>, context: Context) {
val fos: FileOutputStream = context.openFileOutput("map", Context.MODE_PRIVATE)
val os = ObjectOutputStream(fos)
os.writeObject(inputMap)
os.close()
fos.close()
}
fun loadMap(context: Context): MutableMap<Any, Any> {
return try {
val fos: FileInputStream = context.openFileInput("map")
val os = ObjectInputStream(fos)
val map: MutableMap<Any, Any> = os.readObject() as MutableMap<Any, Any>
os.close()
fos.close()
map
} catch (e: Exception) {
mutableMapOf()
}
}
fun deleteMap(context: Context): Boolean {
val file: File = context.getFileStreamPath("map")
return file.delete()
}
用法示例:
var exampleMap: MutableMap<Any, Any> = mutableMapOf()
exampleMap["2"] = 1
saveMap(exampleMap, applicationContext) //save map
exampleMap = loadMap(applicationContext) //load map
【讨论】:
您不需要像其他人建议的那样将 HashMap 保存到文件中。保存 HashMap 和 SharedPreference 并在需要时从 SharedPreference 加载它非常容易。方法如下:
假设你有一个
class T
你的哈希图是:
HashMap<String, T>
转换成字符串后保存如下:
SharedPreferences sharedPref = getSharedPreferences(
"MyPreference", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("MyHashMap", new Gson().toJson(mUsageStatsMap));
editor.apply();
其中mUsageStatsMap定义为:
HashMap<String, T>
以下代码将从保存的共享首选项中读取哈希映射并正确加载回mUsageStatsMap:
Gson gson = new Gson();
String json = sharedPref.getString("MyHashMap", "");
Type typeMyType = new TypeToken<HashMap<String, UsageStats>>(){}.getType();
HashMap<String, UsageStats> usageStatsMap = gson.fromJson(json, typeMyType);
mUsageStatsMap = usageStatsMap;
密钥在 Type typeMyType 中,在 * gson.fromJson(json, typeMyType)* 调用中使用。它使得在 Java 中正确加载哈希映射实例成为可能。
【讨论】:
我知道这有点太晚了,但我希望这对任何阅读者都有帮助..
所以我要做的是
1) 创建HashMap并添加数据 喜欢:-
HashMap hashmapobj = new HashMap();
hashmapobj.put(1001, "I");
hashmapobj.put(1002, "Love");
hashmapobj.put(1003, "Java");
2) 将其写入 shareprefrences 编辑器 喜欢:-
SharedPreferences sharedpreferences = getSharedPreferences(MyPREFERENCES,Context.MODE_PRIVATE);
Editor editor = sharedpreferences.edit();
editor.putStringSet("key", hashmapobj );
editor.apply(); //Note: use commit if u wan to receive response from shp
3) 读取数据,例如:- 在您希望阅读的新课程中
HashMap hashmapobj_RECIVE = new HashMap();
SharedPreferences sharedPreferences (MyPREFERENCES,Context.MODE_PRIVATE;
//reading HashMap from sharedPreferences to new empty HashMap object
hashmapobj_RECIVE = sharedpreferences.getStringSet("key", null);
【讨论】: