将 ArrayList 保存到 SharedPreferences

Posted

技术标签:

【中文标题】将 ArrayList 保存到 SharedPreferences【英文标题】:Save ArrayList to SharedPreferences 【发布时间】:2011-10-26 20:03:37 【问题描述】:

我有一个带有自定义对象的ArrayList。每个自定义对象都包含各种字符串和数字。即使用户离开活动然后想稍后再回来,我也需要数组保持不变,但是在应用程序完全关闭后我不需要可用的数组。我通过使用SharedPreferences 以这种方式保存了许多其他对象,但我不知道如何以这种方式保存整个数组。这可能吗?也许SharedPreferences 不是解决这个问题的方法吗?有没有更简单的方法?

【问题讨论】:

你可以在这里找到答案:***.com/questions/14981233/… 这是完整的例子,通过 url ***.com/a/41137562/4344659 如果有人正在寻找解决方案,这可能是您正在寻找的答案,并提供了 kotlin 中的完整使用示例。 ***.com/a/56873719/3710341 【参考方案1】:

在 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/从SharedPreferences 读取。以下是解决方案:

编辑: 好的,下面是将ArrayList作为序列化对象保存到SharedPreferences,然后从SharedPreferences中读取的解决方案。

由于 API 仅支持从 SharedPreferences 存储和检索字符串(在 API 11 之后,它更简单),我们必须将具有任务列表的 ArrayList 对象序列化和反序列化为字符串。

在TaskManagerApplication类的addTask()方法中,我们要获取共享首选项的实例,然后使用putString()方法存储序列化的ArrayList:

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

您可以从 Apache Pig 项目 ObjectSerializer.java 中获取 ObjectSerializer

【讨论】:

请记住,putStringSet 是在 API 11 中添加的。目前大多数程序员的目标是租赁 API 8 (Froyo)。 我喜欢这种方法的想法,因为它似乎是最干净的,但我要存储的数组是一个自定义类对象,其中包含字符串、双精度和布尔值。如何将所有这 3 种类型添加到集合中?我是否必须将每个单独的对象设置为自己的数组,然后在存储之前将它们单独添加到单独的集合中,还是有更简单的方法? 什么是scoreEditor 致 2016 年 10 月之后的读者:这条评论已经得到了很多人的支持,你可以像我一样使用它,但请停下来,不要这样做。 HashSet 将丢弃重复值,因此您的 ArrayList 将不一样。详情在这里:***.com/questions/12940663/… 提醒那些遇到此答案的人:Set 是无序的,因此保存 StringSet 将失去您在 ArrayList 中的顺序。【参考方案2】:

使用这个对象 --> TinyDB--android-Shared-Preferences-Turbo 非常简单。

TinyDB tinydb = new TinyDB(context);

tinydb.putList("MyUsers", mUsersArray);

得到

tinydb.getList("MyUsers");

更新

可以在此处找到一些有用的示例和故障排除:Android Shared Preference TinyDB putListObject frunction

【讨论】:

这是最好的方法。从我这边 +1 我也是。非常有用! 根据你的List的内容,调用tinydb.putList()的时候要指定你的list的对象类型@看链接页面的例子。 非常爱你! @RAWNAKYAZDANI 默认情况下,TinyDB 会为不存在的值返回一个空列表,因此请检查返回列表的大小;如果它是 0,那么你可以将你想要的任何默认值分配给返回的列表变量。【参考方案3】:

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

SharedPreferences加载Array数据

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


【讨论】:

这是一个非常好的“hack”。请注意,使用此方法,总是有可能使用未使用的旧值使 SharedPreferences 膨胀。例如,一个列表可能在一次运行中的大小为 100,然后大小为 50。50 个旧条目将保留在首选项中。一种方法是设置 MAX 值并清除任何达到该值的内容。 @Iraklis 确实,但假设您只将这个 ArrayList 存储到 SharedPrefeneces 中,您可以使用 mEdit1.clear() 来避免这种情况。 我喜欢这个“黑客”。但是 mEdit1.clear() 会擦除与此目的无关的其他值吗? 谢谢!如果您介意我问,.remove() 是否有必要的用途?偏好不会被覆盖吗?【参考方案4】:

您可以将其转换为JSON String 并将字符串存储在SharedPreferences 中。

【讨论】:

我找到了大量关于将 ArrayLists 转换为 JSONArrays 的代码,但是您是否有一个示例,您可能愿意分享如何转换为 JSONString,以便我可以将其存储在 SharedPrefs 中? 使用toString() 但是如何从 SharedPrefs 中取回它并将其转换回 ArrayList 呢? 很抱歉,我现在没有 Android SDK 来测试它,但请看这里:benjii.me/2010/04/deserializing-json-in-android-using-gson。您应该遍历 json 数组并为每个对象执行它们在那里所做的事情,希望明天我能够通过完整的示例发布对我的答案的编辑。【参考方案5】:

正如@nirav 所说,最好的解决方案是使用 Gson 实用程序类将其作为 json 文本存储在 sharedPrefernces 中。下面的示例代码:

//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>(data);
String jsonText = gson.toJson(textList);
prefsEditor.putString("key", jsonText);
prefsEditor.apply();

【讨论】:

感谢上帝,这是一个救生员。确实很简单。 这个答案应该是向上的。高超!不知道我可以这样使用 Gson。第一次看到这样使用的数组表示法。谢谢! 要将其转换回 List,List textList = Arrays.asList(gson.fromJson(jsonText, String[].class)); 什么是“数据”?【参考方案6】:
/**
 *     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);

科特林

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)

【讨论】:

是的,最佳答案 这是最好的答案,我也一直用它来存储其他对象 你能做到这意味着它将存储所有模型类吗? 是的,我试过了,非常适合将数据存储到 sharedprefs!我投了赞成票。 什么是类型导入?【参考方案7】:

嘿朋友们,我在不使用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.使用packagesharedPreferences()将值存储到sharedPreference:

 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.使用retriveSharedValue()检索sharedPreference的值:

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

希望对你有帮助...

【讨论】:

很好的解决方案!简单快捷! 这将在您添加到集合后立即从列表中删除所有重复的字符串。可能不是想要的功能 是否只针对Strings的列表? 这样你会失去订单【参考方案8】:

Android SharedPreferences 允许您将原始类型(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());

【讨论】:

谢谢。这个答案帮助我检索并保存了我的 List. 谢谢。工作正常【参考方案9】:

这是您的完美解决方案.. 试试吧,

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

【讨论】:

【参考方案10】:

您还可以将 arraylist 转换为 String 并将其保存在首选项中

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;
        

您可以使用convertToString方法将Arraylist转换为字符串后保存,然后使用convertToArray检索字符串并将其转换为数组

在 API 11 之后,您可以直接将设置保存到 SharedPreferences !!! :)

【讨论】:

集合不是列表。列表可以包含重复项并且可以排序。在循环中设置分隔符是没有意义的。应该是一个常数/定义。如果分隔符包含在字符串中,它甚至会这样工作吗?【参考方案11】:

对于 String、int、boolean,最好的选择是 sharedPreferences。

如果你想存储 ArrayList 或任何复杂的数据。最好的选择是 Paper library。

添加依赖

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

【讨论】:

这是我正在寻找的东西。谢谢你:)【参考方案12】:

还有 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() ) 

【讨论】:

【参考方案13】:

最好的方法是使用 GSON 转换为 JSOn 字符串并将此字符串保存到 SharedPreference。 我也用这种方式缓存响应。

【讨论】:

【参考方案14】:

我已阅读以上所有答案。这都是正确的,但我找到了一个更简单的解决方案,如下所示:

    在共享首选项中保存字符串列表>>

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

    以及从共享首选项中获取字符串列表>>

    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是要打开的文件名;不能包含路径分隔符。

【讨论】:

【参考方案15】:

您可以使用 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());

=> 别忘了在你的应用级 build.gradle 中添加 gson 库。

实现'com.google.code.gson:gson:2.8.2'

【讨论】:

【参考方案16】:

您可以参考 FacebookSDK 的 SharedPreferencesTokenCache 类中的 serializeKey() 和 deserializeKey() 函数。 它将supportedType 转换为JSON 对象并将JSON 字符串存储到SharedPreferences 中。您可以从here下载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);
    

【讨论】:

【参考方案17】:

你为什么不把你的arraylist 放在一个Application 类上呢?只有当应用真正被杀死时它才会被销毁,因此,只要应用可用,它就会一直存在。

【讨论】:

如果应用重新启动会怎样。【参考方案18】:

我能找到的最好方法是制作一个二维键数组,并将数组的自定义项放在二维键数组中,然后在启动时通过二维数组检索它。 我不喜欢使用字符串集的想法,因为大多数 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());

【讨论】:

【参考方案19】:

以下代码是公认的答案,对于新手(我)来说还有几行,例如。展示了如何将集合类型对象转换回 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();

【讨论】:

【参考方案20】:
//Set the values
intent.putParcelableArrayListExtra("key",collection);

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

【讨论】:

【参考方案21】:

别忘了实现 Serializable:

Class dataBean implements Serializable
 public String name;

ArrayList<dataBean> dataBeanArrayList = new ArrayList();

https://***.com/a/7635154/4639974

【讨论】:

【参考方案22】:

您可以使用序列化或 Gson 库将列表转换为字符串,反之亦然,然后将字符串保存在首选项中。

使用谷歌的 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;

【讨论】:

【参考方案23】:

使用这个自定义类:

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

【讨论】:

我尝试了几种发布的解决方案,但这是迄今为止最好的。它不需要 GSON,一个特殊的库,转换为 Map 或 SDK 29 之类的东西。我需要存储一个包含三个成员的自定义类,这很容易修改以适应。这应该被投票更高。谢谢,@Yuliia。【参考方案24】:

此方法用于存储/保存数组列表:-

 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;
    

【讨论】:

【参考方案25】:

我使用了相同的方式来保存和检索字符串,但在这里我使用了 HashSet 作为调解器

我们使用 HashSet 将 arrayList 保存到 SharedPreferences:

1- 我们创建 SharedPreferences 变量(在数组发生更改的地方)

2 - 我们将 arrayList 转换为 HashSet

3 - 然后我们将 stringSet 放入并应用

4 - 你在 HashSet 中获取StringSet 并重新创建 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());
    

【讨论】:

【参考方案26】:

您可以将其转换为 Map 对象来存储它,然后在检索 SharedPreferences 时将值更改回 ArrayList。

【讨论】:

【参考方案27】:

在SharedPreferences 中使用getStringSet 和putStringSet 非常简单,但就我而言,我必须先复制Set 对象,然后才能向Set 添加任何内容。否则,如果我的应用程序被强制关闭,Set 将不会被保存。可能是因为下面 API 中的注释。 (如果应用程序被后退按钮关闭,它会保存)。

请注意,您不得修改此调用返回的集合实例。如果您这样做,则无法保证存储数据的一致性,您也无法修改实例。 http://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = prefs.edit();

Set<String> outSet = prefs.getStringSet("key", new HashSet<String>());
Set<String> workingSet = new HashSet<String>(outSet);
workingSet.add("Another String");

editor.putStringSet("key", workingSet);
editor.commit();

【讨论】:

【参考方案28】:

这应该可行:

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;

它对我有用。

【讨论】:

【参考方案29】:

我的 utils 类用于将列表保存到 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);

.Full code of my utils // 使用 Activity 代码中的示例检查

【讨论】:

【参考方案30】:
    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();
        
    

【讨论】:

以上是关于将 ArrayList 保存到 SharedPreferences的主要内容,如果未能解决你的问题,请参考以下文章

Android:将arrayList保存到文件不起作用

将位图从 arraylist 保存到 SD 卡 - 保存的文件不可读

Android:将 ArrayList 保存到 SharedPreferences,但加载它不起作用

如何将加载的数据从Firestore保存到Arraylist

如何将联系人姓名、号码、contact_id 保存到 ArrayList / 联系人选择器

将 Parcelable 对象的 ArrayList 保存为持久数据?