Zapisz ArrayList w SharedPreferences

317

Mam ArrayListniestandardowe obiekty. Każdy obiekt niestandardowy zawiera szereg ciągów i liczb. Potrzebuję tablicy, aby pozostała, nawet jeśli użytkownik opuści aktywność, a następnie chce wrócić później, jednak nie potrzebuję tablicy dostępnej po całkowitym zamknięciu aplikacji. W ten sposób zapisuję wiele innych obiektów, SharedPreferencesale nie mogę wymyślić, jak zapisać w ten sposób całą moją tablicę. czy to możliwe? Może SharedPreferencesnie jest na to sposób? Czy istnieje prostsza metoda?

ryandlf
źródło
Odpowiedź znajdziesz tutaj: stackoverflow.com/questions/14981233/...
Apurva Kolapkar,
to jest kompletny przykład, przejdź przez url stackoverflow.com/a/41137562/4344659
Sanjeev Sangral
Jeśli ktoś szuka rozwiązania, może to być odpowiedź, której szukasz, z pełnym przykładem użycia w kotlin. stackoverflow.com/a/56873719/3710341
Sagar Chapagain

Odpowiedzi:

431

Po API 11 SharedPreferences Editorzaakceptuj Sets. Możesz przekonwertować swoją listę na HashSetcoś podobnego i przechowywać ją w ten sposób. Po ponownym przeczytaniu przekonwertuj go na ArrayList, posortuj w razie potrzeby i możesz zacząć.

//Retrieve the values
Set<String> set = myScores.getStringSet("key", null);

//Set the values
Set<String> set = new HashSet<String>();
set.addAll(listOfExistingScores);
scoreEditor.putStringSet("key", set);
scoreEditor.commit();

Możesz także serializować swój, ArrayLista następnie zapisać / odczytać go do / z SharedPreferences. Poniżej znajduje się rozwiązanie:

EDYCJA:
Ok, poniżej znajduje się rozwiązanie, aby zapisać ArrayListjako obiekt zserializowany, SharedPreferencesa następnie odczytać go z SharedPreferences.

Ponieważ API obsługuje tylko przechowywanie i pobieranie ciągów znaków do / z SharedPreferences (po API 11, jego prostsze), musimy serializować i usuń serializację obiektu ArrayList, który ma listę zadań w łańcuch.

W addTask()metodzie klasy TaskManagerApplication musimy uzyskać instancję współużytkowanej preferencji, a następnie przechowywać zserializowaną ArrayList za pomocą putString()metody:

public void addTask(Task t) {
  if (null == currentTasks) {
    currentTasks = new ArrayList<task>();
  }
  currentTasks.add(t);

  // save the task list to preference
  SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE);
  Editor editor = prefs.edit();
  try {
    editor.putString(TASKS, ObjectSerializer.serialize(currentTasks));
  } catch (IOException e) {
    e.printStackTrace();
  }
  editor.commit();
}

Podobnie musimy pobrać listę zadań z preferencji w onCreate()metodzie:

public void onCreate() {
  super.onCreate();
  if (null == currentTasks) {
    currentTasks = new ArrayList<task>();
  }

  // load tasks from preference
  SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE);

  try {
    currentTasks = (ArrayList<task>) ObjectSerializer.deserialize(prefs.getString(TASKS, ObjectSerializer.serialize(new ArrayList<task>())));
  } catch (IOException e) {
    e.printStackTrace();
  } catch (ClassNotFoundException e) {
    e.printStackTrace();
  }
}

Możesz pobrać ObjectSerializerklasę z projektu Apache Pig ObjectSerializer.java

ten zły
źródło
21
Należy pamiętać, że putStringSetzostał dodany w API 11. Większość obecnych programistów celuje w leasing API 8 (Froyo).
Cristian
2
Podoba mi się pomysł tej metody, ponieważ wydaje się ona najczystsza, ale tablica, którą chcę przechowywać, to obiekt klasy niestandardowej, który zawiera ciągi, liczby podwójne i wartości logiczne. Jak przejść do dodawania wszystkich 3 tych typów do zestawu? Czy muszę ustawić każdy indywidualny obiekt do własnej tablicy, a następnie dodać je osobno do oddzielnych zestawów przed zapisaniem, czy jest prostszy sposób?
ryandlf
5
Co to jest scoreEditor?
Ruchir Baronia 30.01.16
2
Do czytelników po październiku 2016 r .: ten komentarz jest już bardzo pozytywny i możesz go używać tak jak ja, ale proszę, przestań i nie rób tego. HashSet odrzuci zduplikowaną wartość, dlatego twoja ArrayList nie będzie taka sama. Szczegóły tutaj: stackoverflow.com/questions/12940663/…
Seul
2
Dla przypomnienia tym, którzy napotykają tę odpowiedź: zestaw jest nieuporządkowany, więc zapisanie StringSet spowoduje utratę kolejności, jaką posiadałeś z ArrayList.
David Liu,
119

Korzystanie z tego obiektu -> TinyDB - Android-Preferencje współdzielone-Turbo jest bardzo proste.

TinyDB tinydb = new TinyDB(context);

położyć

tinydb.putList("MyUsers", mUsersArray);

dostać

tinydb.getList("MyUsers");

AKTUALIZACJA

Kilka przydatnych przykładów i sposobów rozwiązywania problemów można znaleźć tutaj: Wspólna preferencja Androida TinyDB putListObject frakcja

kc ochibili
źródło
6
To najlepsze podejście. +1 z mojej strony
Sritam Jagadev
3
Ja też. Niezwykle przydatne !!
Juan Aguilar Guisado,
1
w zależności od zawartości listy, podczas wywoływania należy określić typ obiektu listy. tinydb.putList()Spójrz na przykłady na połączonej stronie.
kc ochibili
dobra biblioteka, ale powinienem wspomnieć, że czasami ta biblioteka ma problemy z przechowywaniem obiektów. ściślej mówiąc, może zgłosić wyjątek przepełnienia stosu. i myślę, że dzieje się tak, ponieważ używa refleksji, aby dowiedzieć się, jak przechowywać obiekt, a jeśli obiekt stanie się zbyt skomplikowany, może zgłosić ten wyjątek.
Mr.Q
1
Kocham Cię bardzo!
mychemicalro
93

Zapisywanie Arrayw SharedPreferences:

public static boolean saveArray()
{
    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor mEdit1 = sp.edit();
    /* sKey is an array */
    mEdit1.putInt("Status_size", sKey.size());  

    for(int i=0;i<sKey.size();i++)  
    {
        mEdit1.remove("Status_" + i);
        mEdit1.putString("Status_" + i, sKey.get(i));  
    }

    return mEdit1.commit();     
}

Ładowanie Arraydanych zSharedPreferences

public static void loadArray(Context mContext)
{  
    SharedPreferences mSharedPreference1 =   PreferenceManager.getDefaultSharedPreferences(mContext);
    sKey.clear();
    int size = mSharedPreference1.getInt("Status_size", 0);  

    for(int i=0;i<size;i++) 
    {
     sKey.add(mSharedPreference1.getString("Status_" + i, null));
    }

}
Harneet Kaur
źródło
14
to bardzo fajny „hack”. Należy pamiętać, że dzięki tej metodzie zawsze istnieje możliwość nadmuchania SharedPreferences nieużywanymi starymi wartościami. Na przykład lista może mieć rozmiar 100 w przebiegu, a następnie rozmiar 50. 50 starych pozycji pozostanie w preferencjach. Jednym ze sposobów jest ustawienie wartości MAX i wyczyszczenie czegokolwiek do tego.
Iraklis,
3
@Iraklis Rzeczywiście, ale zakładając, że przechowujesz tylko to ArrayListw sobie, SharedPrefenecesmożesz mEdit1.clear()tego uniknąć.
AlexAndro
1
Lubię ten „hack”. Ale czy mEdit1.clear () usunie inne wartości niezwiązane z tym celem?
Bagusflyer
1
Dzięki! Jeśli masz coś przeciwko, że pytam, czy istnieje konieczny cel .remove ()? Czy preferencje i tak po prostu nie zastąpią?
Script Kitty
62

Możesz przekonwertować go JSON Stringi zapisać ciąg w SharedPreferences.

MByD
źródło
Znajduję mnóstwo kodu podczas konwertowania ArrayLists na JSONArrays, ale czy masz próbkę, którą możesz chcieć podzielić się tym, jak przekonwertować na JSONString, abym mógł przechowywać go w SharedPrefs?
ryandlf
5
using toString ()
MByD
3
Ale w jaki sposób mogę odzyskać go z SharedPrefs i przekonwertować z powrotem na ArrayList?
ryandlf
Przepraszam, nie mam teraz zestawu Android SDK do przetestowania, ale spójrz tutaj: benjii.me/2010/04/deserializing-json-in-android-using-gson . Powinieneś iterować po tablicy json i robić to, co tam robią dla każdego obiektu, mam nadzieję, że będę mógł opublikować edycję do mojej odpowiedzi z pełnym przykładem jutro.
MByD,
53

Jak powiedział @nirav, najlepszym rozwiązaniem jest przechowywanie go w sharedPrefernces jako tekstu json za pomocą klasy narzędziowej Gson. Poniżej przykładowy kod:

//Retrieve the values
Gson gson = new Gson();
String jsonText = Prefs.getString("key", null);
String[] text = gson.fromJson(jsonText, String[].class);  //EDIT: gso to gson


//Set the values
Gson gson = new Gson();
List<String> textList = new ArrayList<String>();
textList.addAll(data);
String jsonText = gson.toJson(textList);
prefsEditor.putString("key", jsonText);
prefsEditor.apply();
Ayman Al-Absi
źródło
2
Dzięki Bogu, to było ratowanie życia. Rzeczywiście bardzo proste.
Parthiban M
2
Ta odpowiedź powinna być znacznie wyższa. Wspaniały! Nie miałem pojęcia, że ​​mogę w ten sposób korzystać z Gsona. Pierwszy raz zobaczyłem notację tablicową również używaną w ten sposób. Dziękuję Ci!
madu
3
Aby przekonwertować go z powrotem na List, List <String> textList = Arrays.asList (gson.fromJson (jsonText, String []. Class));
Vamsi Challa
22

Hej przyjaciele, mam rozwiązanie powyższego problemu bez korzystania z Gsonbiblioteki. Tutaj zamieszczam kod źródłowy.

1. Deklaracja zmienna tj

  SharedPreferences shared;
  ArrayList<String> arrPackage;

2. Zmienna inicjalizacja tj

 shared = getSharedPreferences("App_settings", MODE_PRIVATE);
 // add values for your ArrayList any where...
 arrPackage = new ArrayList<>();

3.Zapisz wartość do sharedPreference, używając packagesharedPreferences():

 private void packagesharedPreferences() {
   SharedPreferences.Editor editor = shared.edit();
   Set<String> set = new HashSet<String>();
   set.addAll(arrPackage);
   editor.putStringSet("DATE_LIST", set);
   editor.apply();
   Log.d("storesharedPreferences",""+set);
 }

4.Usuń wartość sharedPreference za pomocą retriveSharedValue():

 private void retriveSharedValue() {
   Set<String> set = shared.getStringSet("DATE_LIST", null);
   arrPackage.addAll(set);
   Log.d("retrivesharedPreferences",""+set);
 }

Mam nadzieję, że to ci pomoże ...

sachin pangare
źródło
świetne rozwiązanie! łatwo i szybko!
LoveAndroid
5
Spowoduje to usunięcie wszystkich zduplikowanych ciągów z listy, gdy tylko dodasz do zestawu. Prawdopodobnie nie jest to pożądana funkcja
OneCricketeer
Czy to tylko dla listy Strings?
CoolMind
W ten sposób stracisz zamówienie
Brian Reinhold
16
/**
 *     Save and get ArrayList in SharedPreference
 */

JAWA:

public void saveArrayList(ArrayList<String> list, String key){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
    SharedPreferences.Editor editor = prefs.edit();
    Gson gson = new Gson();
    String json = gson.toJson(list);
    editor.putString(key, json);
    editor.apply();    

}

public ArrayList<String> getArrayList(String key){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
    Gson gson = new Gson();
    String json = prefs.getString(key, null);
    Type type = new TypeToken<ArrayList<String>>() {}.getType();
    return gson.fromJson(json, type);
}

Kotlin

fun saveArrayList(list: java.util.ArrayList<String?>?, key: String?) {
    val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
    val editor: Editor = prefs.edit()
    val gson = Gson()
    val json: String = gson.toJson(list)
    editor.putString(key, json)
    editor.apply()
}

fun getArrayList(key: String?): java.util.ArrayList<String?>? {
    val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
    val gson = Gson()
    val json: String = prefs.getString(key, null)
    val type: Type = object : TypeToken<java.util.ArrayList<String?>?>() {}.getType()
    return gson.fromJson(json, type)
}
Raviraj
źródło
1
Tak, najlepsza odpowiedź
AlexPad
to najlepsza odpowiedź, używam jej również do przechowywania innych obiektów
Irfandi D. Vendy
czy możesz to zrobić, co oznacza, że ​​będzie przechowywać wszystkie klasy modeli?
BlackBlind
13

Android SharedPreferances pozwala zapisywać w pamięci pierwotne typy (Boolean, Float, Int, Long, String i StringSet, które są dostępne od API11) jako plik xml.

Kluczową ideą każdego rozwiązania byłoby przekonwertowanie danych na jeden z tych pierwotnych typów.

Osobiście uwielbiam konwertować moją listę do formatu json, a następnie zapisać ją jako ciąg znaków w wartości SharedPreferences.

Aby skorzystać z mojego rozwiązania, musisz dodać bibliotekę Google Gson .

W stopniach po prostu dodaj następującą zależność (użyj najnowszej wersji Google):

compile 'com.google.code.gson:gson:2.6.2'

Zapisz dane (gdzie HttpParam jest twoim obiektem):

List<HttpParam> httpParamList = "**get your list**"
String httpParamJSONList = new Gson().toJson(httpParamList);

SharedPreferences prefs = getSharedPreferences(**"your_prefes_key"**, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(**"your_prefes_key"**, httpParamJSONList);

editor.apply();

Odzyskaj dane (gdzie HttpParam jest twoim obiektem):

SharedPreferences prefs = getSharedPreferences(**"your_prefes_key"**, Context.MODE_PRIVATE);
String httpParamJSONList = prefs.getString(**"your_prefes_key"**, ""); 

List<HttpParam> httpParamList =  
new Gson().fromJson(httpParamJSONList, new TypeToken<List<HttpParam>>() {
            }.getType());
Avi Levin
źródło
Dzięki. Ta odpowiedź pomogła mi odzyskać i zapisać moją listę <Mój obiekt>.
visrahane
Dzięki. Działa dobrze
Velayutham M
11

To jest twoje idealne rozwiązanie .. spróbuj,

public void saveArrayList(ArrayList<String> list, String key){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
    SharedPreferences.Editor editor = prefs.edit();
    Gson gson = new Gson();
    String json = gson.toJson(list);
    editor.putString(key, json);
    editor.apply();     // This line is IMPORTANT !!!
}

public ArrayList<String> getArrayList(String key){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
    Gson gson = new Gson();
    String json = prefs.getString(key, null);
    Type type = new TypeToken<ArrayList<String>>() {}.getType();
    return gson.fromJson(json, type);
}
Krishna Vyas
źródło
9

Możesz także przekonwertować listę arraylist na String i zapisać ją w preferencjach

private String convertToString(ArrayList<String> list) {

            StringBuilder sb = new StringBuilder();
            String delim = "";
            for (String s : list)
            {
                sb.append(delim);
                sb.append(s);;
                delim = ",";
            }
            return sb.toString();
        }

private ArrayList<String> convertToArray(String string) {

            ArrayList<String> list = new ArrayList<String>(Arrays.asList(string.split(",")));
            return list;
        }

Możesz zapisać Arraylist po przekonwertowaniu go na ciąg za pomocą convertToStringmetody, a następnie pobrać ciąg i przekonwertować go na tablicę za pomocąconvertToArray

Po API 11 możesz zapisać zestaw bezpośrednio do SharedPreferences !!! :)

SKT
źródło
6

W przypadku String, int, boolean najlepszym wyborem byłyby sharedPreferences.

Jeśli chcesz przechowywać ArrayList lub dowolne złożone dane. Najlepszym wyborem będzie biblioteka papieru.

Dodaj zależność

implementation 'io.paperdb:paperdb:2.6'

Zainicjuj papier

Należy zainicjować raz w Application.onCreate ():

Paper.init(context);

Zapisać

List<Person> contacts = ...
Paper.book().write("contacts", contacts);

Ładowanie danych

Użyj wartości domyślnych, jeśli obiekt nie istnieje w pamięci.

List<Person> contacts = Paper.book().read("contacts", new ArrayList<>());

Proszę bardzo.

https://github.com/pilgr/Paper

Abdullah Khan
źródło
5

Przeczytałem wszystkie odpowiedzi powyżej. To wszystko prawda, ale znalazłem łatwiejsze rozwiązanie, jak poniżej:

  1. Zapisywanie listy ciągów w preferencjach wspólnych >>

    public static void setSharedPreferenceStringList(Context pContext, String pKey, List<String> pData) {
    SharedPreferences.Editor editor = pContext.getSharedPreferences(Constants.APP_PREFS, Activity.MODE_PRIVATE).edit();
    editor.putInt(pKey + "size", pData.size());
    editor.commit();
    
    for (int i = 0; i < pData.size(); i++) {
        SharedPreferences.Editor editor1 = pContext.getSharedPreferences(Constants.APP_PREFS, Activity.MODE_PRIVATE).edit();
        editor1.putString(pKey + i, (pData.get(i)));
        editor1.commit();
    }

    }

  2. oraz w celu uzyskania listy ciągów z preferencji współdzielonych >>

    public static List<String> getSharedPreferenceStringList(Context pContext, String pKey) {
    int size = pContext.getSharedPreferences(Constants.APP_PREFS, Activity.MODE_PRIVATE).getInt(pKey + "size", 0);
    List<String> list = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        list.add(pContext.getSharedPreferences(Constants.APP_PREFS, Activity.MODE_PRIVATE).getString(pKey + i, ""));
    }
    return list;
    }

Oto Constants.APP_PREFSnazwa pliku do otwarcia; nie może zawierać separatorów ścieżek.

Khemraj
źródło
5

Również z Kotlinem:

fun SharedPreferences.Editor.putIntegerArrayList(key: String, list: ArrayList<Int>?): SharedPreferences.Editor {
    putString(key, list?.joinToString(",") ?: "")
    return this
}

fun SharedPreferences.getIntegerArrayList(key: String, defValue: ArrayList<Int>?): ArrayList<Int>? {
    val value = getString(key, null)
    if (value.isNullOrBlank())
        return defValue
    return ArrayList (value.split(",").map { it.toInt() }) 
}
Andrey Tuzov
źródło
4

Najlepszym sposobem jest konwersja na ciąg JSOn za pomocą GSON i zapisanie tego ciągu na SharedPreference. Korzystam również z tego sposobu buforowania odpowiedzi.

Winston
źródło
4

Możesz zapisać ciąg i niestandardową listę tablic przy użyciu biblioteki Gson.

=> Najpierw musisz utworzyć funkcję, aby zapisać listę tablic w SharedPreferences.

public void saveListInLocal(ArrayList<String> list, String key) {

        SharedPreferences prefs = getSharedPreferences("AppName", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        Gson gson = new Gson();
        String json = gson.toJson(list);
        editor.putString(key, json);
        editor.apply();     // This line is IMPORTANT !!!

    }

=> Musisz utworzyć funkcję, aby uzyskać listę tablic z SharedPreferences.

public ArrayList<String> getListFromLocal(String key)
{
    SharedPreferences prefs = getSharedPreferences("AppName", Context.MODE_PRIVATE);
    Gson gson = new Gson();
    String json = prefs.getString(key, null);
    Type type = new TypeToken<ArrayList<String>>() {}.getType();
    return gson.fromJson(json, type);

}

=> Jak wywołać funkcję zapisywania i pobierania listy tablic.

ArrayList<String> listSave=new ArrayList<>();
listSave.add("test1"));
listSave.add("test2"));
saveListInLocal(listSave,"key");
Log.e("saveArrayList:","Save ArrayList success");
ArrayList<String> listGet=new ArrayList<>();
listGet=getListFromLocal("key");
Log.e("getArrayList:","Get ArrayList size"+listGet.size());

=> Nie zapomnij dodać biblioteki gson do swojego poziomu build.gradle na poziomie aplikacji.

wdrożenie „com.google.code.gson: gson: 2.8.2”

Paras Santoki
źródło
3

Możesz odwoływać się do funkcji serializeKey () i deserializeKey () z klasy SharedPreferencesTokenCache FacebookSDK. Konwertuje obsługiwany typ na obiekt JSON i przechowuje ciąg JSON w SharedPreferences . Możesz pobrać SDK stąd

private void serializeKey(String key, Bundle bundle, SharedPreferences.Editor editor)
    throws JSONException {
    Object value = bundle.get(key);
    if (value == null) {
        // Cannot serialize null values.
        return;
    }

    String supportedType = null;
    JSONArray jsonArray = null;
    JSONObject json = new JSONObject();

    if (value instanceof Byte) {
        supportedType = TYPE_BYTE;
        json.put(JSON_VALUE, ((Byte)value).intValue());
    } else if (value instanceof Short) {
        supportedType = TYPE_SHORT;
        json.put(JSON_VALUE, ((Short)value).intValue());
    } else if (value instanceof Integer) {
        supportedType = TYPE_INTEGER;
        json.put(JSON_VALUE, ((Integer)value).intValue());
    } else if (value instanceof Long) {
        supportedType = TYPE_LONG;
        json.put(JSON_VALUE, ((Long)value).longValue());
    } else if (value instanceof Float) {
        supportedType = TYPE_FLOAT;
        json.put(JSON_VALUE, ((Float)value).doubleValue());
    } else if (value instanceof Double) {
        supportedType = TYPE_DOUBLE;
        json.put(JSON_VALUE, ((Double)value).doubleValue());
    } else if (value instanceof Boolean) {
        supportedType = TYPE_BOOLEAN;
        json.put(JSON_VALUE, ((Boolean)value).booleanValue());
    } else if (value instanceof Character) {
        supportedType = TYPE_CHAR;
        json.put(JSON_VALUE, value.toString());
    } else if (value instanceof String) {
        supportedType = TYPE_STRING;
        json.put(JSON_VALUE, (String)value);
    } else {
        // Optimistically create a JSONArray. If not an array type, we can null
        // it out later
        jsonArray = new JSONArray();
        if (value instanceof byte[]) {
            supportedType = TYPE_BYTE_ARRAY;
            for (byte v : (byte[])value) {
                jsonArray.put((int)v);
            }
        } else if (value instanceof short[]) {
            supportedType = TYPE_SHORT_ARRAY;
            for (short v : (short[])value) {
                jsonArray.put((int)v);
            }
        } else if (value instanceof int[]) {
            supportedType = TYPE_INTEGER_ARRAY;
            for (int v : (int[])value) {
                jsonArray.put(v);
            }
        } else if (value instanceof long[]) {
            supportedType = TYPE_LONG_ARRAY;
            for (long v : (long[])value) {
                jsonArray.put(v);
            }
        } else if (value instanceof float[]) {
            supportedType = TYPE_FLOAT_ARRAY;
            for (float v : (float[])value) {
                jsonArray.put((double)v);
            }
        } else if (value instanceof double[]) {
            supportedType = TYPE_DOUBLE_ARRAY;
            for (double v : (double[])value) {
                jsonArray.put(v);
            }
        } else if (value instanceof boolean[]) {
            supportedType = TYPE_BOOLEAN_ARRAY;
            for (boolean v : (boolean[])value) {
                jsonArray.put(v);
            }
        } else if (value instanceof char[]) {
            supportedType = TYPE_CHAR_ARRAY;
            for (char v : (char[])value) {
                jsonArray.put(String.valueOf(v));
            }
        } else if (value instanceof List<?>) {
            supportedType = TYPE_STRING_LIST;
            @SuppressWarnings("unchecked")
            List<String> stringList = (List<String>)value;
            for (String v : stringList) {
                jsonArray.put((v == null) ? JSONObject.NULL : v);
            }
        } else {
            // Unsupported type. Clear out the array as a precaution even though
            // it is redundant with the null supportedType.
            jsonArray = null;
        }
    }

    if (supportedType != null) {
        json.put(JSON_VALUE_TYPE, supportedType);
        if (jsonArray != null) {
            // If we have an array, it has already been converted to JSON. So use
            // that instead.
            json.putOpt(JSON_VALUE, jsonArray);
        }

        String jsonString = json.toString();
        editor.putString(key, jsonString);
    }
}

private void deserializeKey(String key, Bundle bundle)
        throws JSONException {
    String jsonString = cache.getString(key, "{}");
    JSONObject json = new JSONObject(jsonString);

    String valueType = json.getString(JSON_VALUE_TYPE);

    if (valueType.equals(TYPE_BOOLEAN)) {
        bundle.putBoolean(key, json.getBoolean(JSON_VALUE));
    } else if (valueType.equals(TYPE_BOOLEAN_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        boolean[] array = new boolean[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = jsonArray.getBoolean(i);
        }
        bundle.putBooleanArray(key, array);
    } else if (valueType.equals(TYPE_BYTE)) {
        bundle.putByte(key, (byte)json.getInt(JSON_VALUE));
    } else if (valueType.equals(TYPE_BYTE_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        byte[] array = new byte[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = (byte)jsonArray.getInt(i);
        }
        bundle.putByteArray(key, array);
    } else if (valueType.equals(TYPE_SHORT)) {
        bundle.putShort(key, (short)json.getInt(JSON_VALUE));
    } else if (valueType.equals(TYPE_SHORT_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        short[] array = new short[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = (short)jsonArray.getInt(i);
        }
        bundle.putShortArray(key, array);
    } else if (valueType.equals(TYPE_INTEGER)) {
        bundle.putInt(key, json.getInt(JSON_VALUE));
    } else if (valueType.equals(TYPE_INTEGER_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        int[] array = new int[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = jsonArray.getInt(i);
        }
        bundle.putIntArray(key, array);
    } else if (valueType.equals(TYPE_LONG)) {
        bundle.putLong(key, json.getLong(JSON_VALUE));
    } else if (valueType.equals(TYPE_LONG_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        long[] array = new long[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = jsonArray.getLong(i);
        }
        bundle.putLongArray(key, array);
    } else if (valueType.equals(TYPE_FLOAT)) {
        bundle.putFloat(key, (float)json.getDouble(JSON_VALUE));
    } else if (valueType.equals(TYPE_FLOAT_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        float[] array = new float[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = (float)jsonArray.getDouble(i);
        }
        bundle.putFloatArray(key, array);
    } else if (valueType.equals(TYPE_DOUBLE)) {
        bundle.putDouble(key, json.getDouble(JSON_VALUE));
    } else if (valueType.equals(TYPE_DOUBLE_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        double[] array = new double[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            array[i] = jsonArray.getDouble(i);
        }
        bundle.putDoubleArray(key, array);
    } else if (valueType.equals(TYPE_CHAR)) {
        String charString = json.getString(JSON_VALUE);
        if (charString != null && charString.length() == 1) {
            bundle.putChar(key, charString.charAt(0));
        }
    } else if (valueType.equals(TYPE_CHAR_ARRAY)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        char[] array = new char[jsonArray.length()];
        for (int i = 0; i < array.length; i++) {
            String charString = jsonArray.getString(i);
            if (charString != null && charString.length() == 1) {
                array[i] = charString.charAt(0);
            }
        }
        bundle.putCharArray(key, array);
    } else if (valueType.equals(TYPE_STRING)) {
        bundle.putString(key, json.getString(JSON_VALUE));
    } else if (valueType.equals(TYPE_STRING_LIST)) {
        JSONArray jsonArray = json.getJSONArray(JSON_VALUE);
        int numStrings = jsonArray.length();
        ArrayList<String> stringList = new ArrayList<String>(numStrings);
        for (int i = 0; i < numStrings; i++) {
            Object jsonStringValue = jsonArray.get(i);
            stringList.add(i, jsonStringValue == JSONObject.NULL ? null : (String)jsonStringValue);
        }
        bundle.putStringArrayList(key, stringList);
    }
}
emeraldhieu
źródło
2

Dlaczego nie naklejasz swojej tablicy na klasę aplikacji? Zostaje zniszczony tylko wtedy, gdy aplikacja zostanie naprawdę zabita, więc pozostanie tak długo, jak długo aplikacja będzie dostępna.

Carlos Silva
źródło
5
Co jeśli aplikacja zostanie ponownie uruchomiona ponownie.
Manohar Perepa
2

Najlepszym sposobem, jaki udało mi się znaleźć, jest utworzenie tablicy kluczy 2D i umieszczenie niestandardowych elementów tablicy w tablicy kluczy 2D, a następnie pobranie jej przez tablicę 2D podczas uruchamiania. Nie podobał mi się pomysł użycia zestawu strun, ponieważ większość użytkowników Androida nadal korzysta z Gingerbread, a korzystanie z zestawu strun wymaga plastra miodu.

Przykładowy kod: tutaj ditor jest współdzielonym edytorem wstępnym, a rowitem jest moim niestandardowym obiektem.

editor.putString(genrealfeedkey[j][1], Rowitemslist.get(j).getname());
        editor.putString(genrealfeedkey[j][2], Rowitemslist.get(j).getdescription());
        editor.putString(genrealfeedkey[j][3], Rowitemslist.get(j).getlink());
        editor.putString(genrealfeedkey[j][4], Rowitemslist.get(j).getid());
        editor.putString(genrealfeedkey[j][5], Rowitemslist.get(j).getmessage());
Anshul Bansal
źródło
2

poniższy kod jest akceptowaną odpowiedzią, z kilkoma dodatkowymi wierszami dla nowych ludzi (ja), np. pokazuje, jak przekonwertować obiekt typu zestawu z powrotem na arrayList oraz dodatkowe wskazówki na temat tego, co dzieje się przed „.putStringSet” i „.getStringSet”. (dziękuję ci zło)

// shared preferences
   private SharedPreferences preferences;
   private SharedPreferences.Editor nsuserdefaults;

// setup persistent data
        preferences = this.getSharedPreferences("MyPreferences", MainActivity.MODE_PRIVATE);
        nsuserdefaults = preferences.edit();

        arrayOfMemberUrlsUserIsFollowing = new ArrayList<String>();
        //Retrieve followers from sharedPreferences
        Set<String> set = preferences.getStringSet("following", null);

        if (set == null) {
            // lazy instantiate array
            arrayOfMemberUrlsUserIsFollowing = new ArrayList<String>();
        } else {
            // there is data from previous run
            arrayOfMemberUrlsUserIsFollowing = new ArrayList<>(set);
        }

// convert arraylist to set, and save arrayOfMemberUrlsUserIsFollowing to nsuserdefaults
                Set<String> set = new HashSet<String>();
                set.addAll(arrayOfMemberUrlsUserIsFollowing);
                nsuserdefaults.putStringSet("following", set);
                nsuserdefaults.commit();
tmr
źródło
2
//Set the values
intent.putParcelableArrayListExtra("key",collection);

//Retrieve the values
ArrayList<OnlineMember> onlineMembers = data.getParcelableArrayListExtra("key");
Maulik Gohel
źródło
2

Można użyć serializacji lub biblioteki Gson, aby przekonwertować listę na ciąg znaków i odwrotnie, a następnie zapisać ciąg w preferencjach.

Korzystając z biblioteki Google Gson:

//Converting list to string
new Gson().toJson(list);

//Converting string to list
new Gson().fromJson(listString, CustomObjectsList.class);

Korzystanie z serializacji Java:

//Converting list to string
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(list);
oos.flush();
String string = Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT);
oos.close();
bos.close();
return string;

//Converting string to list
byte[] bytesArray = Base64.decode(familiarVisitsString, Base64.DEFAULT);
ByteArrayInputStream bis = new ByteArrayInputStream(bytesArray);
ObjectInputStream ois = new ObjectInputStream(bis);
Object clone = ois.readObject();
ois.close();
bis.close();
return (CustomObjectsList) clone;
Farhan
źródło
2

Ta metoda służy do przechowywania / zapisywania listy tablic: -

 public static void saveSharedPreferencesLogList(Context context, List<String> collageList) {
            SharedPreferences mPrefs = context.getSharedPreferences("PhotoCollage", context.MODE_PRIVATE);
            SharedPreferences.Editor prefsEditor = mPrefs.edit();
            Gson gson = new Gson();
            String json = gson.toJson(collageList);
            prefsEditor.putString("myJson", json);
            prefsEditor.commit();
        }

Ta metoda służy do pobierania listy tablic:

public static List<String> loadSharedPreferencesLogList(Context context) {
        List<String> savedCollage = new ArrayList<String>();
        SharedPreferences mPrefs = context.getSharedPreferences("PhotoCollage", context.MODE_PRIVATE);
        Gson gson = new Gson();
        String json = mPrefs.getString("myJson", "");
        if (json.isEmpty()) {
            savedCollage = new ArrayList<String>();
        } else {
            Type type = new TypeToken<List<String>>() {
            }.getType();
            savedCollage = gson.fromJson(json, type);
        }

        return savedCollage;
    }
Anil Singhania
źródło
1

Możesz przekonwertować go na Mapobiekt, aby go zapisać, a następnie zmienić wartości z powrotem na ArrayList podczas pobierania SharedPreferences.

Phil
źródło
1

Użyj tej niestandardowej klasy:

public class SharedPreferencesUtil {

    public static void pushStringList(SharedPreferences sharedPref, 
                                      List<String> list, String uniqueListName) {

        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putInt(uniqueListName + "_size", list.size());

        for (int i = 0; i < list.size(); i++) {
            editor.remove(uniqueListName + i);
            editor.putString(uniqueListName + i, list.get(i));
        }
        editor.apply();
    }

    public static List<String> pullStringList(SharedPreferences sharedPref, 
                                              String uniqueListName) {

        List<String> result = new ArrayList<>();
        int size = sharedPref.getInt(uniqueListName + "_size", 0);

        for (int i = 0; i < size; i++) {
            result.add(sharedPref.getString(uniqueListName + i, null));
        }
        return result;
    }
}

Jak używać:

SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferencesUtil.pushStringList(sharedPref, list, getString(R.string.list_name));
List<String> list = SharedPreferencesUtil.pullStringList(sharedPref, getString(R.string.list_name));
Julia Ashomok
źródło
1

to powinno działać:

public void setSections (Context c,  List<Section> sectionList){
    this.sectionList = sectionList;

    Type sectionListType = new TypeToken<ArrayList<Section>>(){}.getType();
    String sectionListString = new Gson().toJson(sectionList,sectionListType);

    SharedPreferences.Editor editor = getSharedPreferences(c).edit().putString(PREFS_KEY_SECTIONS, sectionListString);
    editor.apply();
}

je, aby to złapać:

public List<Section> getSections(Context c){

    if(this.sectionList == null){
        String sSections = getSharedPreferences(c).getString(PREFS_KEY_SECTIONS, null);

        if(sSections == null){
            return new ArrayList<>();
        }

        Type sectionListType = new TypeToken<ArrayList<Section>>(){}.getType();
        try {

            this.sectionList = new Gson().fromJson(sSections, sectionListType);

            if(this.sectionList == null){
                return new ArrayList<>();
            }
        }catch (JsonSyntaxException ex){

            return new ArrayList<>();

        }catch (JsonParseException exc){

            return new ArrayList<>();
        }
    }
    return this.sectionList;
}

mi to pasuje.

Ruben Caster
źródło
1

Moja klasa utils do listy zapisywania w SharedPreferences

public class SharedPrefApi {
    private SharedPreferences sharedPreferences;
    private Gson gson;

    public SharedPrefApi(Context context, Gson gson) {
        this.sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.gson = gson;
    } 

    ...

    public <T> void putList(String key, List<T> list) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, gson.toJson(list));
        editor.apply();
    }

    public <T> List<T> getList(String key, Class<T> clazz) {
        Type typeOfT = TypeToken.getParameterized(List.class, clazz).getType();
        return gson.fromJson(getString(key, null), typeOfT);
    }
}

Za pomocą

// for save
sharedPrefApi.putList(SharedPrefApi.Key.USER_LIST, userList);

// for retrieve
List<User> userList = sharedPrefApi.getList(SharedPrefApi.Key.USER_LIST, User.class);

.
Pełny kod moich narzędzi // sprawdź, korzystając z przykładu w kodzie działania

Phan Van Linh
źródło
1

Użyłem tego samego sposobu zapisywania i pobierania ciągu, ale tutaj z tablicą tablic użyłem HashSet jako mediatora

Aby zapisać arrayList w SharedPreferences, używamy HashSet:

1- tworzymy zmienną SharedPreferences (w miejscu, w którym następuje zmiana w tablicy)

2 - konwertujemy arrayList na HashSet

3 - następnie kładziemy stringSet i stosujemy

4 - dostajeszStringSet w HashSet i ponownie tworzysz ArrayList, aby ustawić HashSet.

public class MainActivity extends AppCompatActivity {
    ArrayList<String> arrayList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SharedPreferences prefs = this.getSharedPreferences("com.example.nec.myapplication", Context.MODE_PRIVATE);

        HashSet<String> set = new HashSet(arrayList);
        prefs.edit().putStringSet("names", set).apply();


        set = (HashSet<String>) prefs.getStringSet("names", null);
        arrayList = new ArrayList(set);

        Log.i("array list", arrayList.toString());
    }
}
NEC
źródło
0
    public  void saveUserName(Context con,String username)
    {
        try
        {
            usernameSharedPreferences= PreferenceManager.getDefaultSharedPreferences(con);
            usernameEditor = usernameSharedPreferences.edit();
            usernameEditor.putInt(PREFS_KEY_SIZE,(USERNAME.size()+1)); 
            int size=USERNAME.size();//USERNAME is arrayList
            usernameEditor.putString(PREFS_KEY_USERNAME+size,username);
            usernameEditor.commit();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }
    public void loadUserName(Context con)
    {  
        try
        {
            usernameSharedPreferences= PreferenceManager.getDefaultSharedPreferences(con);
            size=usernameSharedPreferences.getInt(PREFS_KEY_SIZE,size);
            USERNAME.clear();
            for(int i=0;i<size;i++)
            { 
                String username1="";
                username1=usernameSharedPreferences.getString(PREFS_KEY_USERNAME+i,username1);
                USERNAME.add(username1);
            }
            usernameArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, USERNAME);
            username.setAdapter(usernameArrayAdapter);
            username.setThreshold(0);

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
użytkownik4680583
źródło
0

Wszystkie powyższe odpowiedzi są poprawne. :) Sam użyłem jednego z nich do mojej sytuacji. Jednak kiedy przeczytałem pytanie, odkryłem, że OP mówi o innym scenariuszu niż tytuł tego postu, jeśli nie pomyliłem się.

„Potrzebuję, aby tablica pozostała, nawet jeśli użytkownik porzuci aktywność, a następnie wróci później”

W rzeczywistości chce, aby dane były przechowywane do momentu otwarcia aplikacji, niezależnie od zmieniających się ekranów użytkownika w aplikacji.

„jednak nie potrzebuję tablicy dostępnej po całkowitym zamknięciu aplikacji”

Ale kiedy aplikacja zostanie zamknięta, dane nie powinny zostać zachowane SharedPreferences nie jest optymalnym sposobem na to.

Aby spełnić ten wymóg, można stworzyć klasę, która się rozszerza Application klasę.

public class MyApp extends Application {

    //Pardon me for using global ;)

    private ArrayList<CustomObject> globalArray;

    public void setGlobalArrayOfCustomObjects(ArrayList<CustomObject> newArray){
        globalArray = newArray; 
    }

    public ArrayList<CustomObject> getGlobalArrayOfCustomObjects(){
        return globalArray;
    }

}

Za pomocą narzędzia do ustawiania i pobierania można uzyskać dostęp do ArrayList z dowolnego miejsca za pomocą aplikacji. A najlepsze jest to, że po zamknięciu aplikacji nie musimy się martwić o przechowywanie danych. :)

Atul O Holic
źródło