Chcę zapisać/przywołać tablicę całkowitą za pomocą SharedPreferences, czy to możliwe?Jak mogę przechowywać tablicę całkowitą w SharedPreferences?
Odpowiedz
Można spróbować zrobić to w następujący sposób:
Połóż na ciąg liczb całkowitych, wyznaczających każdy int przez postać, na przykład przecinek, a następnie zapisać je jako wyrażenie:
SharedPreferences prefs = getPreferences(MODE_PRIVATE); int[] list = new int[10]; StringBuilder str = new StringBuilder(); for (int i = 0; i < list.length; i++) { str.append(list[i]).append(","); } prefs.edit().putString("string", str.toString());
uzyskać s tring i analizować je za pomocą StringTokenizer:
String savedString = prefs.getString("string", ""); StringTokenizer st = new StringTokenizer(savedString, ","); int[] savedList = new int[10]; for (int i = 0; i < 10; i++) { savedList[i] = Integer.parseInt(st.nextToken()); }
Można zapisać tylko wartości pierwotne w sharedPreference
. Zamiast tego użyj Sqlite
.
nie można umieścić tablice w sharedPrefs, ale można obejść:
public void storeIntArray(String name, int[] array){
SharedPreferences.Editor edit= mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE).edit();
edit.putInt("Count_" + name, array.length);
int count = 0;
for (int i: array){
edit.putInt("IntValue_" + name + count++, i);
}
edit.commit();
}
public int[] getFromPrefs(String name){
int[] ret;
SharedPreferences prefs = mContext.getSharedPreferences("NAME", Context.MODE_PRIVATE);
int count = prefs.getInt("Count_" + name, 0);
ret = new int[count];
for (int i = 0; i < count; i++){
ret[i] = prefs.getInt("IntValue_"+ name + i, i);
}
return ret;
}
Zapomniałeś zadzwonić commit(). –
Masz rację! zaktualizowano go –
Oto moja wersja, na podstawie odpowiedzi Egor za. Wolę nie używać StringBuilder, chyba że buduję ogromny ciąg, ale dzięki Egorowi za używanie StringTokenizera - nie wykorzystałem tego w przeszłości, ale jest bardzo przydatny! FYI, to poszedł w mojej klasie użytkowy:
public static void saveIntListPrefs(
String name, Activity activity, List<Integer> list)
{
String s = "";
for (Integer i : list) {
s += i + ",";
}
Editor editor = activity.getPreferences(Context.MODE_PRIVATE).edit();
editor.putString(name, s);
editor.commit();
}
public static ArrayList<Integer> readIntArrayPrefs(String name, Activity activity)
{
SharedPreferences prefs = activity.getPreferences(Context.MODE_PRIVATE);
String s = prefs.getString(name, "");
StringTokenizer st = new StringTokenizer(s, ",");
ArrayList<Integer> result = new ArrayList<Integer>();
while (st.hasMoreTokens()) {
result.add(Integer.parseInt(st.nextToken()));
}
return result;
}
dwa rozwiązania:
(1) Użyj http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
To Split/dołączyć funkcje, które pozwalają łączyć i podzielić liczby całkowite w jednej wkładki:
StringUtils.join([1, 2, 3], ';') = "1;2;3"
StringUtils.split("1;2;3", ';') = ["1", "2", "3"]
Nadal trzeba jednak konwertować łańcuchy z powrotem na liczby całkowite.
Właściwie do dzielenia java.lang.String.split()
będzie działać tak samo dobrze: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)
(2) Użyj SharedPreferences.putStringSet (API) (11):
SharedPreferences.Editor editor = preferences.edit();
int count = this.intSet.size();
if (count > 0) {
Set<String> theSet = new HashSet<String>();
for (Long l : this.intSet) {
theSet.add(String.valueOf(l));
}
editor.putStringSet(PREFS_KEY, theSet);
} else {
editor.remove(PREFS_KEY);
}
editor.commit();
i uzyskać je z powrotem:
Set<String> theSet = this.preferences.getStringSet(PREFS_KEY, null);
if (theSet != null && !theSet.isEmpty()) {
this.intSet.clear();
for (String s : theSet) {
this.intSet.add(Integer.valueOf(s));
}
}
Ten kod nie przechwytuje wartości NPE lub NumberFormatExceptions, ponieważ intSet jest w inny sposób zabezpieczony przed nie t zawierają wszelkie wartości null. Ale oczywiście, jeśli nie możesz zapewnić, że w swoim kodzie powinieneś otoczyć to spróbuj/catch.
Lubię używać JSON, który może być przechowywany i pobierany jako ciąg znaków, w celu reprezentowania złożonych danych w SharedPreferences. Tak więc, w przypadku int tablicy:
public void setPrefIntArray(String tag, int[] value)
{
SharedPreferences.Editor prefEditor = PreferenceManager.getDefaultSharedPreferences(context)
.edit();
String s;
try
{
JSONArray jsonArr = new JSONArray();
for (int i : value)
jsonArr.put(i);
JSONObject json = new JSONObject();
json.put(tag, jsonArr);
s = json.toString();
}
catch(JSONException excp)
{
s = "";
}
prefEditor.putString(tag, s);
prefEditor.commit();
}
public int[] getPrefIntArray(String tag, int[] defaultValue)
{
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
String s = pref.getString(tag, "");
try
{
JSONObject json = new JSONObject(new JSONTokener(s));
JSONArray jsonArr = json.getJSONArray(tag);
int[] result = new int[jsonArr.length()];
for (int i = 0; i < jsonArr.length(); i++)
result[i] = jsonArr.getInt(i);
return result;
}
catch(JSONException excp)
{
return defaultValue;
}
}
Piękno jest to, że sama idea może mieć zastosowanie do wszelkich innych złożonych reprezentowana danych jako JSON.
Oto, w jaki sposób „przekonwertować do oddzielonych przecinkami String” rozwiązanie może wyglądać w Kotlin, zaimplementowane jako funkcje rozszerzeń:
fun SharedPreferences.Editor.putIntArray(key: String, value: IntArray): SharedPreferences.Editor {
return putString(key, value.joinToString(
separator = ",",
transform = { it.toString() }))
}
fun SharedPreferences.getIntArray(key: String): IntArray {
with(getString(key, "")) {
with(if(isNotEmpty()) split(',') else return intArrayOf()) {
return IntArray(count(), { this[it].toInt() })
}
}
}
ten sposób można użyć putIntArray(String, IntArray)
i getIntArray(String)
podobnie jak inne put i określonych metod :
Należy zauważyć, że tej metody można używać tylko wtedy, gdy dysponujesz małą ilością danych, ponieważ operacje ciągów nie są wydajne. (każda postać musi być analizowana podczas czytania). –
Zgodnie z javadoc, odradza się używanie StringTokenizer: http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html, zamiast tego użyj String.split(). Zobacz tutaj http://stackoverflow.com/questions/6983856/why-is-stringtokenizer-deprecated –