Сохранить ArrayList в SharedPreferences


318

У меня есть ArrayListс пользовательскими объектами. Каждый пользовательский объект содержит различные строки и числа. Мне нужно, чтобы массив оставался без присмотра, даже если пользователь покидает действие и затем хочет вернуться позже, однако мне не нужен массив, доступный после того, как приложение было полностью закрыто. Таким способом я сохраняю множество других объектов, SharedPreferencesно не могу понять, как сохранить весь массив таким образом. Это возможно? Может быть SharedPreferences, не так ли? Есть ли более простой способ?


Вы можете найти ответ здесь: stackoverflow.com/questions/14981233/…
Apurva Kolapkar

это полный пример, перейдите по ссылке stackoverflow.com/a/41137562/4344659
Санджив Санграл

Если кто-то ищет решение, это может быть ответ, который вы ищете, с полным примером использования в kotlin. stackoverflow.com/a/56873719/3710341
Сагар Чапагейн

Ответы:


432

После API 11 SharedPreferences Editorпринять Sets. Вы можете преобразовать свой Список в HashSetили что-то подобное и сохранить его таким образом. Когда вы прочитаете его обратно, преобразуйте его в ArrayList, сортируйте, если нужно, и все готово.

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

Вы также можете сериализовать свой ArrayListи затем сохранить / прочитать его в / из SharedPreferences. Ниже приведено решение:

РЕДАКТИРОВАТЬ:
Хорошо, ниже приведено решение для сохранения в ArrayListвиде сериализованного объекта SharedPreferencesи последующего чтения его из SharedPreferences.

Поскольку API поддерживает только сохранение и извлечение строк в / из SharedPreferences (после API 11, это проще), мы должны сериализовать и десериализовать объект ArrayList, который имеет список задач в строку.

В addTask()методе класса TaskManagerApplication мы должны получить экземпляр общего предпочтения и затем сохранить сериализованный ArrayList, используя putString()метод:

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

Точно так же мы должны получить список задач из предпочтения в onCreate()методе:

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

Вы можете получить ObjectSerializerкласс из проекта Apache Pig ObjectSerializer.java


21
Имейте в виду, что это putStringSetбыло добавлено в API 11. Большинство современных программистов ориентированы на аренду API 8 (Froyo).
Кристиан

2
Мне нравится идея этого метода, потому что он кажется самым чистым, но массив, который я хочу сохранить, представляет собой объект пользовательского класса, который содержит строки, двойные и логические значения. Как мне добавить все эти три типа в набор? Нужно ли устанавливать каждый отдельный объект в свой собственный массив, а затем добавлять их по отдельности в отдельные наборы перед сохранением, или есть более простой способ?
ryandlf

5
Что такое scoreEditor?
Ручир Барония

2
Читателям после октября 2016 года: этот комментарий уже получил много голосов, и вы можете использовать его как я, но, пожалуйста, остановитесь и не делайте этого. HashSet отбросит дублирующее значение, поэтому ваш ArrayList не будет таким же. Подробности здесь: stackoverflow.com/questions/12940663/…
Сеул

2
В качестве напоминания для тех, кто сталкивался с этим ответом: набор неупорядочен, поэтому сохранение набора StringSet приведет к потере порядка, который вы имели с вашим ArrayList.
Дэвид Лю

119

Использование этого объекта -> TinyDB - Android-Shared-Preferences-Turbo очень просто.

TinyDB tinydb = new TinyDB(context);

класть

tinydb.putList("MyUsers", mUsersArray);

получить

tinydb.getList("MyUsers");

ОБНОВИТЬ

Некоторые полезные примеры и устранение неполадок могут быть найдены здесь: Android Shared Preference TinyDB putListObject frunction


6
Это лучший подход. +1 с моей стороны
Сритам Джагадев

3
Я тоже. Очень полезно!
Хуан Агилар Гисадо

1
в зависимости от содержимого вашего списка, вы должны указать тип объекта вашего списка при вызове. tinydb.putList()Посмотрите примеры на связанной странице.
kc ochibili

хорошая библиотека, но я должен отметить, что иногда эта библиотека имеет проблемы при хранении объектов. чтобы быть более конкретным, это может вызвать исключение переполнения стека. и я думаю, что это потому, что он использует отражение, чтобы выяснить, как хранить объект, и если объект становится слишком сложным, он может вызвать это исключение.
Mr.Q

1
Я так тебя люблю!
mychemicalro

93

Сохранение Arrayв 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();     
}

Загрузка Arrayданных изSharedPreferences

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

}

14
это очень хороший "хак". Имейте в виду, что с помощью этого метода всегда есть возможность раздувать SharedPreferences с неиспользованными старыми значениями. Например, список может иметь размер 100 при запуске, а затем размер 50. 50 старых записей останутся в настройках. Одним из способов является установка значения MAX и очистка чего-либо до этого.
Ираклис

3
@Iraklis Действительно, но при условии, что вы храните только это ArrayListв себе, SharedPrefenecesвы могли mEdit1.clear()бы избежать этого.
AlexAndro

1
Мне нравится этот "взломать". Но mEdit1.clear () сотрет другие значения, не относящиеся к этой цели?
Bagusflyer

1
Спасибо! Если вы не возражаете, я спрашиваю, есть ли необходимая цель для .remove ()? Разве предпочтение просто не переписать в любом случае?
Сценарий Китти

62

Вы можете преобразовать его JSON Stringи сохранить строку в SharedPreferences.


Я нашел тонну кода для преобразования ArrayLists в JSONArrays, но есть ли у вас пример, которым вы могли бы поделиться, как конвертировать в JSONString, чтобы я мог сохранить его в SharedPrefs?
ryandlf

5
использование toString ()
MByD

3
Но тогда как мне вернуть его из SharedPrefs и преобразовать обратно в ArrayList?
ryandlf

Извините, у меня нет Android SDK для тестирования, но посмотрите здесь: benjii.me/2010/04/deserializing-json-in-android-using-gson . Вы должны перебрать массив json и сделать то, что они делают там для каждого объекта, надеюсь, я смогу опубликовать редактирование моего ответа с полным примером завтра.
MByD

53

Как сказал @nirav, лучшее решение - сохранить его в sharedPrefernces как текст json с помощью служебного класса Gson. Ниже пример кода:

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

2
Слава Богу, это спасло жизнь. Очень просто.
Партибан М

2
Этот ответ должен быть далеко вверх. Superb! Я понятия не имел, что могу использовать Gson таким образом. Первый раз, чтобы увидеть обозначение массива, использовался таким же образом. Спасибо!
Madu

3
Чтобы преобразовать его обратно в список, List <String> textList = Arrays.asList (gson.fromJson (jsonText, String []. Class));
Вамси Чалла

22

Привет друзья, я получил решение вышеуказанной проблемы без использования Gsonбиблиотеки. Здесь я размещаю исходный код.

1. Переменная декларация т.е.

  SharedPreferences shared;
  ArrayList<String> arrPackage;

2. Переменная инициализация т.е.

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

3. Сохраните значение в sharedPreference, используя 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. Получить значение sharedPreference с помощью retriveSharedValue():

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

Я надеюсь, что это будет полезно для вас ...


отличное решение! легко и быстро!
LoveAndroid

5
Это удалит все повторяющиеся строки из списка, как только вы добавите в набор. Вероятно, не
нужная

Это только для списка Stringс?
CoolMind

Вы потеряете порядок таким образом
Брайан Рейнхольд

16
/**
 *     Save and get ArrayList in SharedPreference
 */

ЯВА:

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

Котлин

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

1
Да, лучший ответ
AlexPad

это лучший ответ, я тоже использовал его для хранения других объектов
Ирфанди Д. Венди

Вы можете сделать это, что означает, что он будет хранить все модели класса?
BlackBlind

13

Android SharedPreferances позволяет вам сохранять примитивные типы (Boolean, Float, Int, Long, String и StringSet, доступные с API11) в памяти в виде XML-файла.

Ключевой идеей любого решения было бы преобразование данных в один из этих примитивных типов.

Я лично люблю конвертировать мой список в формат json, а затем сохранять его как строку в значении SharedPreferences.

Чтобы использовать мое решение, вам нужно добавить Google Gson lib.

В Gradle просто добавьте следующую зависимость (пожалуйста, используйте последнюю версию Google):

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

Сохраните данные (где HttpParam - ваш объект):

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

Получить данные (где HttpParam - ваш объект):

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

Спасибо. Этот ответ помог мне найти и сохранить мой список <MyObject>.
Висрахане

Спасибо. Работает отлично
Velayutham M

11

Это ваше идеальное решение .. попробуйте,

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

9

Вы также можете преобразовать массив в строку и сохранить его в настройках

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

Вы можете сохранить Arraylist после преобразования его в строку, используя convertToStringметод, получить строку и преобразовать ее в массив, используяconvertToArray

После API 11 вы можете сохранить набор непосредственно в SharedPreferences, хотя !!! :)


6

Для String, int, boolean лучшим выбором будут sharedPreferences.

Если вы хотите хранить ArrayList или любые сложные данные. Лучшим выбором была бы Бумажная библиотека.

Добавить зависимость

implementation 'io.paperdb:paperdb:2.6'

Инициализировать бумагу

Должен быть инициализирован один раз в Application.onCreate ():

Paper.init(context);

Сохранить

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

Загрузка данных

Используйте значения по умолчанию, если объект не существует в хранилище.

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

Ну вот.

https://github.com/pilgr/Paper


5

Я прочитал все ответы выше. Это все правильно, но я нашел более простое решение, как показано ниже:

  1. Сохранение списка строк в общих настройках >>

    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. и для получения списка строк из общих настроек >>

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

Вот Constants.APP_PREFSимя файла, который нужно открыть; не может содержать разделители пути.


5

Также с 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() }) 
}

4

лучший способ - преобразовать строку JSOn с помощью GSON и сохранить эту строку в SharedPreference. Я также использую этот способ для кэширования ответов.


4

Вы можете сохранить список строк и пользовательских массивов с помощью библиотеки Gson.

=> Сначала вам нужно создать функцию для сохранения списка массивов в 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 !!!

    }

=> Вам нужно создать функцию для получения списка массивов из 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);

}

=> Как вызвать функцию сохранения и получения списка массивов.

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

=> Не забудьте добавить библиотеку gson в свой уровень приложения build.gradle.

реализация 'com.google.code.gson: gson: 2.8.2'


3

Вы можете ссылаться на функции serializeKey () и deserializeKey () из класса SharedPreferencesTokenCache FacebookSDK. Он преобразует поддерживаемый тип в объект JSON и сохраняет строку JSON в SharedPreferences . Вы можете скачать SDK отсюда

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

2

Почему бы вам не прикрепить свой arraylist к классу Application? Оно разрушается только тогда, когда приложение действительно убито, поэтому оно будет сохраняться, пока приложение доступно.


5
Что делать, если приложение снова запускается.
Манохар Перепа

2

Лучший способ, который мне удалось найти, - это создать двумерный массив ключей и поместить пользовательские элементы массива в двумерный массив ключей, а затем получить его через двумерный массив при запуске. Мне не понравилась идея использования набора строк, потому что большинство пользователей Android все еще используют Gingerbread, а использование набора строк требует соты.

Пример кода: здесь ditor - это общий преф-редактор, а rowitem - мой пользовательский объект.

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

2

следующий код является принятым ответом, с еще несколькими строками для новых людей (я), например. показывает, как преобразовать объект заданного типа обратно в arrayList, и дополнительные рекомендации по поводу того, что стоит перед «.putStringSet» и «.getStringSet». (спасибо, злобный)

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

2
//Set the values
intent.putParcelableArrayListExtra("key",collection);

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


2

Вы можете использовать сериализацию или библиотеку Gson для преобразования списка в строку и наоборот, а затем сохранить строку в настройках.

Используя библиотеку Google Gson:

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

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

Используя сериализацию 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;

2

Этот метод используется для хранения / сохранения списка массивов: -

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

Этот метод используется для получения списка массивов:

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

1

Вы можете преобразовать его в Mapобъект, чтобы сохранить его, а затем изменить значения обратно на ArrayList при получении SharedPreferences.


1

Используйте этот пользовательский класс:

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

Как пользоваться:

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

1

это должно работать:

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

их, чтобы поймать это просто

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

меня устраивает.


1

Мой класс утилит для сохранения списка в 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);
    }
}

С помощью

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

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

,
Полный код моих утилит // проверьте с помощью примера в коде активности


1

Я использовал тот же способ сохранения и извлечения строки, но здесь с arrayList я использовал HashSet в качестве посредника

Чтобы сохранить arrayList в SharedPreferences, мы используем HashSet:

1- мы создаем переменную SharedPreferences (в месте, где изменение происходит с массивом)

2 - конвертируем arrayList в HashSet

3 - тогда мы ставим строку Set и применяем

4 - вы получаете StStringSet внутри HashSet и воссоздаете ArrayList для установки 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());
    }
}

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

0

Все вышеприведенные ответы верны. :) Я сам использовал один из них для моей ситуации. Однако, когда я прочитал вопрос, я обнаружил, что ОП на самом деле говорит о сценарии, отличном от названия этого поста, если я не понял его неправильно.

«Мне нужно, чтобы массив оставался без присмотра, даже если пользователь покидает действие, а затем хочет вернуться позже»

Он на самом деле хочет, чтобы данные сохранялись до тех пор, пока приложение не будет открыто, независимо от смены экрана пользователем в приложении.

«Однако мне не нужен массив, доступный после полного закрытия приложения»

Но как только приложение закрыто, данные не должны сохраняться. Поэтому я чувствую, что использую SharedPreferences не является оптимальным способом для этого.

Что можно сделать для этого требования, так это создать класс, который расширяет Applicationкласс.

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

}

Используя сеттер и геттер, вы можете получить доступ к ArrayList из любой точки приложения. И что самое приятное, когда приложение закрывается, нам не нужно беспокоиться о сохранении данных. :)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.