共享首选项覆盖
Shared prefrence overwrites
我在共享首选项中保存了一个字符串集,该字符串集加载到我的监视列表中。当用户单击电影页面中的按钮时,它会获取电影的名称、标题和发行日期并将它们存储在 JSON object 中。它们都存储为字符串。当我尝试在观看列表中添加一部电影时,问题仍然存在,我添加的每部新电影,最后一部电影都会被覆盖,这意味着我的观看列表中始终只能有一部电影。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sharedPreferences = getSharedPreferences("WatchlistData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
JSONObject obj = new JSONObject();
try {
obj.put("name", name);
obj.put("date", releaseDate);
obj.put("platform", platform);
} catch (JSONException e) {
e.printStackTrace();
}
Set<String> set = new HashSet<String>();
set.add(obj.toString());
editor.putStringSet("setOfStrings", set);
editor.commit(); //saved
}
});
监视列表片段 OnCreateView
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_watchlist, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.watchlist);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mWatchlistAdapter = new WatchlistAdapter(getActivity(), loadFromStorage());
mWatchlistAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mWatchlistAdapter);
return view;
}
loadFromStorage,在recyclerview中加载我的xml文件,这个方法在我的适配器构造函数中传递。
SharedPreferences mPrefs = getActivity().getSharedPreferences("WatchlistData", Context.MODE_PRIVATE);
ArrayList<watchlist> items = new ArrayList<watchlist>();
Set<String> set = mPrefs.getStringSet("setOfStrings", null); //retrieving set of strings
if (set == null){
Toast.makeText(getActivity(), "No data found", Toast.LENGTH_LONG).show();
} else {
//for every string in set
for (String s : set) {
try {
JSONObject jsonObject = new JSONObject(s); //for every JSONObject String
String name = jsonObject.getString("name");
String date = jsonObject.getString("date");
String platform = jsonObject.getString("platform");
watchlist newGame = new watchlist();
newGame.setGame(name);
newGame.setDate(date);
newGame.setPlatform(platform);
items.add(newGame);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return items;
}
看起来你每次在 SharedPreferences 中放置一些东西时只是覆盖了字符串集,这就是为什么你只看到最后一个结果的原因:
Set<String> set = new HashSet<String>();
set.add(obj.toString());
editor.putStringSet("setOfStrings", set);
您刚刚在每次点击时创建了一个新的 'set' 并将其保存到 "setOfStrings"。
我自己正在考虑为一个项目实现类似的实现,但发现从 SharedPreferences 操作 StringSet 变成了一个问题。作为参考,[Android 开发者网站上的文档](http://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet(java.lang.String, java.util.Set))
状态,
"Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all."
有解决方法,但据我了解,最好避免对此类数据使用 SharedPreferences,因为它只是保存为 xml 文件,容易出现问题- 您可能需要考虑在 SQLite 数据库中实现该信息。
默认情况下SharedPreferences
用新数据替换旧数据。你可以做的是,先获取旧数据,然后附加新数据,
//Extract the value stored in SharedPreferences
String value = prefs.getString(<Key>, <DefaultValue>);
//Append to the extracted value
String appendedValue = append(value, newValue);
//Write the result back to SharedPreferences
editor.putString(<Key>, appendedValue).commit();
SharedPreferenced
用于轻量级数据但不适用于大量存储。因此,根据您的要求,您应该将数据写入外部存储中的 JSON/XML 文件,稍后再读回。
我在共享首选项中保存了一个字符串集,该字符串集加载到我的监视列表中。当用户单击电影页面中的按钮时,它会获取电影的名称、标题和发行日期并将它们存储在 JSON object 中。它们都存储为字符串。当我尝试在观看列表中添加一部电影时,问题仍然存在,我添加的每部新电影,最后一部电影都会被覆盖,这意味着我的观看列表中始终只能有一部电影。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences sharedPreferences = getSharedPreferences("WatchlistData", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
JSONObject obj = new JSONObject();
try {
obj.put("name", name);
obj.put("date", releaseDate);
obj.put("platform", platform);
} catch (JSONException e) {
e.printStackTrace();
}
Set<String> set = new HashSet<String>();
set.add(obj.toString());
editor.putStringSet("setOfStrings", set);
editor.commit(); //saved
}
});
监视列表片段 OnCreateView
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_watchlist, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.watchlist);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mWatchlistAdapter = new WatchlistAdapter(getActivity(), loadFromStorage());
mWatchlistAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mWatchlistAdapter);
return view;
}
loadFromStorage,在recyclerview中加载我的xml文件,这个方法在我的适配器构造函数中传递。
SharedPreferences mPrefs = getActivity().getSharedPreferences("WatchlistData", Context.MODE_PRIVATE);
ArrayList<watchlist> items = new ArrayList<watchlist>();
Set<String> set = mPrefs.getStringSet("setOfStrings", null); //retrieving set of strings
if (set == null){
Toast.makeText(getActivity(), "No data found", Toast.LENGTH_LONG).show();
} else {
//for every string in set
for (String s : set) {
try {
JSONObject jsonObject = new JSONObject(s); //for every JSONObject String
String name = jsonObject.getString("name");
String date = jsonObject.getString("date");
String platform = jsonObject.getString("platform");
watchlist newGame = new watchlist();
newGame.setGame(name);
newGame.setDate(date);
newGame.setPlatform(platform);
items.add(newGame);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return items;
}
看起来你每次在 SharedPreferences 中放置一些东西时只是覆盖了字符串集,这就是为什么你只看到最后一个结果的原因:
Set<String> set = new HashSet<String>();
set.add(obj.toString());
editor.putStringSet("setOfStrings", set);
您刚刚在每次点击时创建了一个新的 'set' 并将其保存到 "setOfStrings"。
我自己正在考虑为一个项目实现类似的实现,但发现从 SharedPreferences 操作 StringSet 变成了一个问题。作为参考,[Android 开发者网站上的文档](http://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet(java.lang.String, java.util.Set)) 状态, "Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all."
有解决方法,但据我了解,最好避免对此类数据使用 SharedPreferences,因为它只是保存为 xml 文件,容易出现问题- 您可能需要考虑在 SQLite 数据库中实现该信息。
默认情况下SharedPreferences
用新数据替换旧数据。你可以做的是,先获取旧数据,然后附加新数据,
//Extract the value stored in SharedPreferences
String value = prefs.getString(<Key>, <DefaultValue>);
//Append to the extracted value
String appendedValue = append(value, newValue);
//Write the result back to SharedPreferences
editor.putString(<Key>, appendedValue).commit();
SharedPreferenced
用于轻量级数据但不适用于大量存储。因此,根据您的要求,您应该将数据写入外部存储中的 JSON/XML 文件,稍后再读回。