2011-08-24 7 views

Odpowiedz

41

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()); 
    } 
    
+1

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). –

+1

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 –

0

Można zapisać tylko wartości pierwotne w sharedPreference. Zamiast tego użyj Sqlite.

14

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; 
} 
+0

Zapomniałeś zadzwonić commit(). –

+0

Masz rację! zaktualizowano go –

5

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; 
} 
3

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.

+0

Rozwiązanie 2 to sposób, aby przejść – Cobbles

+0

Drugie rozwiązanie jest ładne, ale straci kolejność elementów. – blackwolf

+0

@blackwolf Wypróbuj za pomocą 'java.util.SortedSet' - być może Android serializuje go poprawnie. – Risadinha

1

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.

0

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 :