将ArrayList保存到SharedPreferences

我有一个ArrayList与自定义对象。 每个自定义对象都包含各种string和数字。 即使用户离开活动,然后想要稍后再回来,我也需要数组来保持,但是在完全closures应用程序后我不需要数组。 我通过使用SharedPreferences以这种方式保存了很多其他对象,但我无法弄清楚如何以这种方式保存整个数组。 这可能吗? 也许SharedPreferences不是这样的呢? 有一个更简单的方法吗?

在API 11之后, SharedPreferences Editor接受Sets 。 你可以将你的列表转换成一个HashSet或类似的东西,并像这样存储。 当你读回来的时候,把它转换成一个ArrayList ,如果需要的话sorting,你很好。

 //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或从中读取。 以下是解决scheme:

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

因为API只支持存储和从SharedPreferences中检索string(在API 11之后,它更简单),我们必须将具有任务列表的ArrayList对象序列化并反序列化为string。

在TaskManagerApplication类的addTask()方法中,我们必须获取共享首选项的实例,然后使用addTask()方法存储序列化的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

在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加载数组数据

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

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

 TinyDB tinydb = new TinyDB(context); 

放在

 tinydb.putList("MyUsers", mUsersArray); 

要得到

 tinydb.getList("MyUsers"); 

您可以将其转换为JSONstring并将该string存储在共享首选项中。

正如@ n​​irav所说,最好的解决scheme是使用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>(); textList.addAll(data); String jsonText = gson.toJson(textList); prefsEditor.putString("key", jsonText); prefsEditor.commit(); 

嘿朋友,我没有使用Gson库,得到了上述问题的解决scheme。 在这里我发布源代码。

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

我希望这对你有帮助

Android SharedPreferances允许您保存内存中的原始types(布尔型,Float,Int,Long,String和StringSet),作为一个xml文件。

任何解决scheme的关键思想是将数据转换为其中一种基本types。

我个人喜欢将我的列表转换为json格式,然后将其保存为SharedPreferences值中的string。

为了使用我的解决scheme,您必须添加Google Gson lib。

在gradle中,只需添加以下依赖项(请使用谷歌的最新版本):

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

最好的方法是使用GSON转换为JSOnstring并将此string保存到SharedPreference。 我也用这种方式来caching响应。

你可以从FacebookSDK的SharedPreferencesTokenCache类中引用serializeKey()和deserializeKey()函数。 它将supportedType转换成JSON对象并将JSONstring存储到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); } } 

您也可以将数组列表转换为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方法将其转换为string之后保存Arraylist,并检索string并使用convertToArray将其转换为数组

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

我已阅读上面的所有答案。 这是完全正确的,但我发现一个更简单的解决scheme如下:

1)在共享首选项>>中保存string列表

 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),并从共享首选项>>获取string列表

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

你为什么不把你的数组列表粘在一个应用程序类上? 它只会在应用程序真正被杀时被破坏,所以只要应用程序可用,它就会一直存在。

我已经能够find的最佳方法是制作二维数组键,并将数组的自定义项放入二维数组键中,然后在启动时通过二维数组进行检索。 我不喜欢使用string集的想法,因为大多数android用户仍然在姜饼上,使用string集需要蜂窝。

示例代码:这里的ditor是共享的pref编辑器,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()); 

下面的代码是被接受的答案,对于新人(我)还有几行,例如。 展示了如何将settypes的对象转换回arrayList,以及关于“.putStringSet”和“.getStringSet”之前的其他指导。 (谢谢evilone)

 // 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(); 
 //Set the values intent.putParcelableArrayListExtra("key",collection); //Retrieve the values ArrayList<OnlineMember> onlineMembers = data.getParcelableArrayListExtra("key"); 

不要忘记实现Serializable:

 Class dataBean implements Serializable{ public String name; } ArrayList<dataBean> dataBeanArrayList = new ArrayList(); 

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

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

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

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

以上所有答案都是正确的。 :)我自己用我的情况之一。 然而,当我读到这个问题时,我发现OP实际上是在讨论与本文标题不同的场景,如果我没有弄错的话。

“即使用户离开活动,然后又想再回来,我仍然需要这个arrays”

他实际上希望数据被存储直到应用程序被打开,而不pipe用户在应用程序中改变屏幕。

“但是,我不需要应用程序已经完全closures后可用的arrays”

但是,一旦应用程序closures,数据不应该保存。因此,我觉得使用SharedPreferences不是最佳的方式。

对此需求可以做的是创build一个扩展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; } } 

使用setter和getter,可以从应用程序的任何地方访问ArrayList。 最好的部分是一旦应用程序closures,我们不必担心数据被存储。 🙂

在SharedPreferences中使用getStringSet和putStringSet非常简单,但在我的情况下,我必须复制Set对象才能向Set中添加任何内容。 否则,如果我的应用程序强制closures,则不会保存设置。 可能是因为下面的API中的注释。 (虽然如果应用程序closures后退button保存)。

请注意,您不得修改此调用返回的设置实例。 存储的数据的一致性不能保证,如果你这样做,也没有能力修改实例。 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(); 

使用这个自定义类:

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