Guardar ArrayList en SharedPreferences

318

Tengo un ArrayListcon objetos personalizados. Cada objeto personalizado contiene una variedad de cadenas y números. Necesito que la matriz permanezca, incluso si el usuario deja la actividad y luego quiere volver más tarde, sin embargo, no necesito la matriz disponible después de que la aplicación se haya cerrado por completo. Guardo muchos otros objetos de esta manera usando el SharedPreferencespero no puedo entender cómo guardar mi matriz completa de esta manera. es posible? Tal vez SharedPreferencesno es la forma de hacerlo. ¿Hay un método más simple?

ryandlf
fuente
Puede encontrar la respuesta aquí: stackoverflow.com/questions/14981233/…
Apurva Kolapkar
este es el ejemplo completo, vaya a la URL stackoverflow.com/a/41137562/4344659
Sanjeev Sangral
Si alguien está buscando la solución, esta podría ser la respuesta que está buscando con un ejemplo de uso completo en kotlin. stackoverflow.com/a/56873719/3710341
Sagar Chapagain

Respuestas:

432

Después de API 11 la SharedPreferences Editoracepta Sets. Puede convertir su Lista en HashSetalgo similar y almacenarla así. Cuando lo leas de nuevo, conviértelo en un ArrayList, clasifícalo si es necesario y listo.

//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();

También puede serializar su ArrayListy luego guardarlo / leerlo en / desde SharedPreferences. A continuación se muestra la solución:

EDITAR:
Ok, a continuación se muestra la solución para guardar ArrayListcomo objeto serializado enSharedPreferences y luego leerlo desde SharedPreferences.

Debido a que API solo admite el almacenamiento y la recuperación de cadenas hacia / desde SharedPreferences (después de API 11, es más simple), tenemos que serializar y deserializar el objeto ArrayList que tiene la lista de tareas en cadena.

En el addTask()método de la clase TaskManagerApplication, tenemos que obtener la instancia de la preferencia compartida y luego almacenar la ArrayList serializada usando el putString()método:

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

Del mismo modo, tenemos que recuperar la lista de tareas de la preferencia en el onCreate()método:

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

Puede obtener ObjectSerializerclase del proyecto ObjectSerializer.java de Apache Pig .

maligno
fuente
21
Tenga en cuenta que putStringSetse agregó en la API 11. La mayoría de los programadores actuales apuntan al arrendamiento API 8 (Froyo).
Cristian
2
Me gusta la idea de este método porque parece ser el más limpio, pero la matriz que estoy buscando almacenar es un objeto de clase personalizado que contiene cadenas, dobles y booleanos. ¿Cómo hago para agregar los 3 de estos tipos a un conjunto? ¿Tengo que configurar cada objeto individual en su propia matriz y luego agregarlos individualmente a conjuntos separados antes de almacenarlos, o hay una forma más simple?
ryandlf
55
¿Qué es scoreEditor?
Ruchir Baronia
2
Para los lectores después de octubre de 2016: Este comentario ya recibe una gran cantidad de votos positivos y puede usarlo como yo, pero por favor deténgase y no haga esto. HashSet descartará el valor duplicado, por lo tanto, su ArrayList no será la misma. Detalles aquí: stackoverflow.com/questions/12940663/…
seúl
2
Como recordatorio para los que se encuentran con esta respuesta: un conjunto no está ordenado, por lo que guardar un StringSet perderá el orden que tenía con su ArrayList.
David Liu
119

Usar este objeto -> TinyDB - Android-Shared-Preferences-Turbo es muy simple.

TinyDB tinydb = new TinyDB(context);

poner

tinydb.putList("MyUsers", mUsersArray);

Llegar

tinydb.getList("MyUsers");

ACTUALIZAR

Algunos ejemplos útiles y solución de problemas se pueden encontrar aquí: Android Shared Preference TinyDB putListObject frunction

kc ochibili
fuente
66
Este es el mejor enfoque. +1 de mi lado
Sritam Jagadev
3
Yo también. ¡Extremadamente útil!
Juan Aguilar Guisado
1
dependiendo del contenido de su Lista, debe especificar el tipo de objeto de su lista cuando llame. tinydb.putList()Mire los ejemplos en la página vinculada.
kc ochibili
buena lib, pero debo mencionar que a veces esta biblioteca tiene problemas al almacenar objetos. para ser más específico, puede arrojar una excepción de desbordamiento de pila. y creo que es porque usa la reflexión para descubrir cómo almacenar el objeto, y si el objeto se complica demasiado, puede arrojar esa excepción.
Mr.Q
1
¡Los quiero mucho!
mychemicalro
93

Guardando Arrayen 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();     
}

Cargando Arraydatos deSharedPreferences

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
fuente
14
Este es un muy buen "hack". Tenga en cuenta que con este método, siempre existe la posibilidad de inflar SharedPreferences con valores antiguos no utilizados. Por ejemplo, una lista puede tener un tamaño de 100 en una ejecución y luego un tamaño de 50. Las 50 entradas antiguas permanecerán en las preferencias. Una forma es establecer un valor MÁXIMO y borrar cualquier cosa hasta eso.
Iraklis
3
@Iraklis hecho, pero suponiendo que almacene sólo que esta ArrayListen SharedPrefenecesusted podría utilizar mEdit1.clear()para evitar esto.
AlexAndro
1
Me gusta este "hack". Pero mEdit1.clear () borrará otros valores que no sean relevantes para este propósito?
Bagusflyer
1
¡Gracias! Si le molesta que pregunte, ¿hay un propósito necesario para .remove ()? ¿No se sobrescribirá la preferencia de todos modos?
Script Kitty
62

Puede convertirlo JSON Stringy almacenar la cadena en SharedPreferences.

MByD
fuente
Estoy encontrando un montón de código para convertir ArrayLists a JSONArrays, pero ¿tiene una muestra que podría estar dispuesto a compartir sobre cómo convertir a JSONString para que pueda almacenarla en SharedPrefs?
ryandlf
55
usando toString ()
MByD
3
Pero entonces, ¿cómo puedo recuperarlo de SharedPrefs y convertirlo nuevamente en una ArrayList?
ryandlf
Lo siento, no tengo un SDK de Android para probarlo ahora, pero eche un vistazo aquí: benjii.me/2010/04/deserializing-json-in-android-using-gson . Debería iterar sobre la matriz json y hacer lo que hacen allí para cada objeto, espero poder publicar una edición de mi respuesta con un ejemplo completo mañana.
MByD
53

Como dijo @nirav, la mejor solución es almacenarlo en SharedPrefernces como un texto json utilizando la clase de utilidad Gson. Debajo del código de muestra:

//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
fuente
2
Gracias a Dios, eso fue un salvavidas. Muy simple de hecho.
Parthiban M
2
Esta respuesta debería estar muy arriba. ¡Magnífico! No tenía idea de que puedo usar Gson de esta manera. La primera vez que veo la notación de matriz también se usa de esta manera. ¡Gracias!
madu
3
Para volver a convertirlo en List, List <String> textList = Arrays.asList (gson.fromJson (jsonText, String []. Class));
Vamsi Challa
22

Hola amigos, obtuve la solución del problema anterior sin usar Gson biblioteca. Aquí publico el código fuente.

1. Declaración variable, es decir

  SharedPreferences shared;
  ArrayList<String> arrPackage;

2.Inicialización variable, es decir

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

3. Almacene el valor en sharedPreference usando 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. Recuperar el valor de sharedPreference usando retriveSharedValue():

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

Espero que te sea útil ...

sachin pangare
fuente
gran solución! ¡fácil y rápido!
LoveAndroid
55
Esto eliminaría todas las cadenas duplicadas de la lista tan pronto como agregue a un conjunto. Probablemente no sea una característica deseada
OneCricketeer
¿Es solo para una lista de Strings?
CoolMind
Perderás el orden de esta manera
Brian Reinhold
16
/**
 *     Save and get ArrayList in SharedPreference
 */

JAVA:

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
fuente
1
Sí, la mejor respuesta
AlexPad el
esta es la mejor respuesta, también la he estado usando para almacenar otros objetos
Irfandi D. Vendy
¿Puedes hacer esto que significa que almacenará toda la clase de modelo?
BlackBlind
13

Android SharedPreferances le permite guardar tipos primitivos (Boolean, Float, Int, Long, String y StringSet que están disponibles desde API11) en la memoria como un archivo xml.

La idea clave de cualquier solución sería convertir los datos a uno de esos tipos primitivos.

Personalmente me encanta convertir mi lista a formato json y luego guardarla como una Cadena en un valor de Preferencias Compartidas.

Para utilizar mi solución, deberá agregar Google Gson lib.

En gradle simplemente agregue la siguiente dependencia (use la última versión de google):

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

Guardar datos (donde HttpParam es su objeto):

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();

Recuperar datos (donde HttpParam es su objeto):

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
fuente
Gracias. Esta respuesta me ayudó a recuperar y guardar mi Lista <MiObjeto>.
visrahane
Gracias. Trabajando bien
Velayutham M
11

Esta es tu solución perfecta ... pruébalo,

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
fuente
9

También puede convertir la lista de arrays en una cadena y guardarla con preferencia

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

Puede guardar la Arraylist después de convertirla en cadena usando el convertToStringmétodo y recuperar la cadena y convertirla en matriz usandoconvertToArray

¡Después de API 11, puede guardar el conjunto directamente en SharedPreferences ! :)

SKT
fuente
6

Para String, int, boolean, la mejor opción sería sharedPreferences.

Si desea almacenar ArrayList o cualquier información compleja. La mejor opción sería la biblioteca de papel.

Agregar dependencia

implementation 'io.paperdb:paperdb:2.6'

Inicializar papel

Debe inicializarse una vez en Application.onCreate ():

Paper.init(context);

Salvar

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

Cargando datos

Utilice valores predeterminados si el objeto no existe en el almacenamiento.

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

Aqui tienes.

https://github.com/pilgr/Paper

Abdullah Khan
fuente
5

He leído todas las respuestas anteriores. Eso es todo correcto, pero encontré una solución más fácil como a continuación:

  1. Guardar lista de cadenas en preferencia compartida >>

    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. y para obtener la lista de cadenas de preferencia compartida >>

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

Aquí Constants.APP_PREFSestá el nombre del archivo a abrir; no puede contener separadores de ruta.

Khemraj
fuente
5

También con Kotlin:

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
fuente
4

La mejor manera es convertirlo a una cadena JSOn usando GSON y guardar esta cadena en SharedPreference. También uso esta forma para almacenar en caché las respuestas.

Winston
fuente
4

Puede guardar cadenas y listas de matrices personalizadas utilizando la biblioteca Gson.

=> Primero necesita crear una función para guardar la lista de matrices en 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 !!!

    }

=> Necesita crear una función para obtener una lista de matriz de 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);

}

=> Cómo llamar a guardar y recuperar la función de lista de matriz.

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());

=> No olvide agregar la biblioteca gson en su nivel de aplicación build.gradle.

implementación 'com.google.code.gson: gson: 2.8.2'

Paras Santoki
fuente
3

Puede consultar las funciones serializeKey () y deserializeKey () de la clase SharedPreferencesTokenCache de FacebookSDK. Convierte el tipo compatible en el objeto JSON y almacena la cadena JSON en SharedPreferences . Puedes descargar SDK desde aquí

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);
    }
}
esmeralda
fuente
2

¿Por qué no pegas tu lista de arrays en una clase de aplicación? Solo se destruye cuando la aplicación se mata realmente , por lo que permanecerá durante el tiempo que la aplicación esté disponible.

Carlos Silva
fuente
55
¿Qué pasa si la aplicación se vuelve a lanzar de nuevo?
Manohar Perepa
2

La mejor manera que he podido encontrar es hacer una matriz 2D de claves y colocar los elementos personalizados de la matriz en la matriz 2D de teclas y luego recuperarla a través de la matriz 2D al inicio. No me gustó la idea de usar el conjunto de cadenas porque la mayoría de los usuarios de Android todavía están en Gingerbread y el uso del conjunto de cadenas requiere panal.

Código de muestra: aquí ditor es el editor de preferencias compartido y rowitem es mi objeto personalizado.

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
fuente
2

El siguiente código es la respuesta aceptada, con algunas líneas más para gente nueva (yo), por ejemplo. muestra cómo volver a convertir el objeto de tipo set en arrayList, y una guía adicional sobre lo que sucede antes de '.putStringSet' y '.getStringSet'. (gracias malvado)

// 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
fuente
2
//Set the values
intent.putParcelableArrayListExtra("key",collection);

//Retrieve the values
ArrayList<OnlineMember> onlineMembers = data.getParcelableArrayListExtra("key");
Maulik Gohel
fuente
2

Puede usar la serialización o la biblioteca Gson para convertir la lista a cadena y viceversa y luego guardar la cadena en las preferencias.

Usando la biblioteca Gson de google:

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

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

Usando la serialización de 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
fuente
2

Este método se utiliza para almacenar / guardar la lista de la matriz: -

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

Este método se utiliza para recuperar la lista de matriz: -

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
fuente
1

Puede convertirlo en un MapObjeto para almacenarlo, luego volver a cambiar los valores a ArrayList cuando recupere el SharedPreferences.

Phil
fuente
1

Use esta clase personalizada:

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

Cómo utilizar:

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));
Yuliia Ashomok
fuente
1

Esto debería funcionar:

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

ellos, para atraparlo solo:

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

esto funciona para mi.

Ruben Caster
fuente
1

Mi clase de utilidades para guardar lista en 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);
    }
}

Utilizando

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

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

.
Código completo de mis utilidades // verificar usando el ejemplo en Código de actividad

Phan Van Linh
fuente
1

Utilicé la misma manera de guardar y recuperar una cadena, pero aquí con arrayList he utilizado HashSet como mediador

Para guardar arrayList en SharedPreferences utilizamos HashSet:

1- creamos la variable SharedPreferences (en el lugar donde ocurre el cambio en la matriz)

2 - convertimos el arrayList a HashSet

3 - luego ponemos el stringSet y aplicamos

4: obtienes SetStringSet dentro de HashSet y vuelves a crear ArrayList para configurar 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());
    }
}
Comité ejecutivo nacional
fuente
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();
        }
    }
usuario4680583
fuente
0

Todas las respuestas anteriores son correctas. :) Yo mismo usé uno de estos para mi situación. Sin embargo, cuando leí la pregunta, descubrí que el OP en realidad está hablando de un escenario diferente al título de esta publicación, si no me equivoqué.

"Necesito que la matriz permanezca, incluso si el usuario deja la actividad y luego quiere volver más tarde"

En realidad, quiere que los datos se almacenen hasta que la aplicación esté abierta, independientemente de que el usuario cambie las pantallas dentro de la aplicación.

"Sin embargo, no necesito la matriz disponible después de que la aplicación se haya cerrado por completo"

Pero una vez que la aplicación se cierra, los datos no deben conservarse. SharedPreferences no es la forma óptima de hacerlo.

Lo que se puede hacer para este requisito es crear una clase que extienda la Applicationclase.

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

}

Usando el setter y getter, se puede acceder a ArrayList desde cualquier lugar dentro de la Aplicación. Y la mejor parte es que una vez que se cierra la aplicación, no tenemos que preocuparnos por los datos que se almacenan. :)

Atul O Holic
fuente