Can't Control Order Of String Set In Shared Preferences
Solution 1:
It is unfortunate, but you have simply found a limitation of SharedPreferences
.
While you are using an orderd hash, it does not load them ordered when you call getStringSet
.
The quickest simplest way I have found of doing this is to convert your array into text, ordered, and then save that into the SharedPreferences. Android comes with an object JSONArray
that can do this.
http://developer.android.com/reference/org/json/JSONArray.html
Here is some pseudo code that will do what you want:
publicvoidsaveOrderedCollection(Collection collection, String key){
JSONArray jsonArray = newJSONArray(collection);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, jsonArray.toString());
editor.commit();
}
publicCollectionloadOrderedCollection(String key){
ArrayList arrayList = newArrayList;
SharedPreferences.Editor editor = sharedPreferences.edit();
JSONArray jsonArray = newJSONArray(editor.getString(key, "[]"));
for (int i = 0; i < jsonArray.length(); i++) {
arrayList.put(jsonArray.get(i));
}
return arrayList;
}
Here are some other posts that I used to make this:
Is it possible to add an array or object to SharedPreferences on Android
In shared preferences how to store string array in android application
Solution 2:
I've implemented the changes suggested (using JSON strings instead of string sets when saving to shared prefs) and here's the new code for my shared pref class in case anyone else is trying to do the same thing. Probably overkill on the troubleshooting logs but thats how I roll since I don't know how to debug properly.
package [];
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Created by Programming on 2/22/2016.
*/publicclassSharedPrefUTIL {
protectedstatic final StringTAG = "CXX SharedPrefUTIL";
Context context;
SharedPreferences sharedPreferences;
Set<String> recentArray;
Set<String> blockArray;
Set<String> faveArray;
JSONArray recentJArray;
JSONArray blockJArray;
JSONArray faveJArray;
publicSharedPrefUTIL(Context context){
this.context = context;
// START load arrays from shared prefs
sharedPreferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
try {
recentJArray = newJSONArray(sharedPreferences.getString("recentArray","[]"));
blockJArray = newJSONArray(sharedPreferences.getString("blockArray","[]"));
faveJArray = newJSONArray(sharedPreferences.getString("faveArray","[]"));
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, e.toString());
}
Log.i(TAG, "length of recentJArray is " + recentJArray.length());
recentArray = newLinkedHashSet<String>();
blockArray = newLinkedHashSet<String>();
faveArray = newLinkedHashSet<String>();
for (int i = 0; i < recentJArray.length(); i++) {
try {
recentArray.add(recentJArray.getString(i));
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, e.toString());
}
}
for (int i = 0; i < blockJArray.length(); i++) {
try {
blockArray.add(blockJArray.getString(i));
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, e.toString());
}
}
for (int i = 0; i < faveJArray.length(); i++) {
try {
faveArray.add(faveJArray.getString(i));
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, e.toString());
}
}
// END load arrays from shared prefsLog.i(TAG, "SharedPrefUTIL instance created");
}
publicvoidtoastLength(Stringtype){
if (type == "R"){
String temp = type + " array is this long: " + recentArray.size();
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, temp);
}
elseif (type == "B"){
String temp = type + " array is this long: " + blockArray.size();
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, temp);
}
elseif (type == "F"){
String temp = type + " array is this long: " + faveArray.size();
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, temp);
}
else {
Log.i(TAG, "invalid type param given to toastLength()");
}
}
publicvoidtoastContents(Stringtype){
if (type == "R"){
for (String temp : recentArray) {
Toast.makeText(context, temp, Toast.LENGTH_LONG).show();
Log.i(TAG, "recentArray contains: " + temp);
}
}
elseif (type == "B"){
for (String temp : blockArray) {
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, "blockArray contains: " + temp);
}
}
elseif (type == "F"){
for (String temp : faveArray) {
Toast.makeText(context, temp,
Toast.LENGTH_LONG).show();
Log.i(TAG, "faveArray contains: " + temp);
}
}
else {
Log.i(TAG, "invalid type param given to toastContents()");
}
}
publicvoidclearList(Stringtype){
if (type == "R"){
recentArray.clear();
commit("recentArray", recentArray);
Toast.makeText(context,"recent list has been cleared.", Toast.LENGTH_LONG);
}
elseif (type == "B"){
blockArray.clear();
commit("blockArray", blockArray);
Toast.makeText(context,"blacklist has been cleared.", Toast.LENGTH_LONG);
}
elseif (type == "F"){
faveArray.clear();
commit("faveArray", faveArray);
Toast.makeText(context,"favorites have been cleared.", Toast.LENGTH_LONG);
}
else {
Log.i(TAG, "invalid type param given to clearList()");
}
}
publicvoidaddRecent(String newRecent){
recentArray.add(newRecent);
commit("recentArray", recentArray);
Log.i(TAG, newRecent + " added to recentArray");
}
publicvoidaddBlocked(String newBlocked){
blockArray.add(newBlocked);
commit("blockArray", blockArray);
Toast.makeText(context, newBlocked + " has been blacklisted!", Toast.LENGTH_SHORT);
}
publicvoidremBlocked(String remBlocked){
blockArray.remove(remBlocked);
commit("blockArray", blockArray);
Toast.makeText(context, remBlocked + " has been unblocked.", Toast.LENGTH_SHORT);
}
publicvoidaddFave(String newFave){
faveArray.add(newFave);
commit("faveArray", faveArray);
Toast.makeText(context, newFave + " added to favorites!", Toast.LENGTH_SHORT);
}
publicvoidremFave(String remFave){
faveArray.remove(remFave);
commit("faveArray", faveArray);
Toast.makeText(context, remFave + " removed from favorites.", Toast.LENGTH_SHORT);
}
publicvoidcommit(String key, Set<String> set){
// convert set into JSONJSONArray jsonArray = newJSONArray(set);
Log.i(TAG, "During commit, jsonArray(set) is this long: " + jsonArray.length());
//-------------------------------------------// commit changesSharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key,jsonArray.toString());
editor.commit();
Log.i(TAG, jsonArray.toString() + " committed to " + key);
}
}
Solution 3:
Using kotlin, you could simply write extension functions to store a list of strings which keeps the ordering as you've added them:
fun SharedPreferences.Editor.putStringList(key: String, list: List<String>) {
this.putString(key, list.joinToString(";"))
}
fun SharedPreferences.getStringList(key: String): List<String> {
returnthis.getString(key, "")?.split(";") ?: listOf()
}
You can then store your values like this:
sharedPrefs.edit().putStringList("SOME_KEY", listOf("A", "B", "C"))
And receive them likes this:
valmyList= sharedPrefs.getStringList("SOME_KEY")
Post a Comment for "Can't Control Order Of String Set In Shared Preferences"