将ArrayList保存到SharedPreferences

rya*_*dlf 297 android arraylist sharedpreferences

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

evi*_*one 412

在API 11之后SharedPreferences Editor接受Sets.您可以将List转换为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();
Run Code Online (Sandbox Code Playgroud)

您也可以序列化您的ArrayList,然后保存/读取它SharedPreferences.以下是解决方案:

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

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

addTask()TaskManagerApplication类的方法中,我们必须获取共享首选项的实例,然后使用以下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();
}
Run Code Online (Sandbox Code Playgroud)

同样,我们必须从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();
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 请记住,在API 11中添加了`putStringSet`.大多数当前程序员的目标是租用API 8(Froyo). (20认同)
  • 什么是`scoreEditor`? (5认同)
  • 作为对遇到此答案的人的提醒:Set 是无序的,因此保存 StringSet 将失去使用 ArrayList 的顺序。 (4认同)
  • 我喜欢这种方法的想法,因为它似乎是最干净的,但我想要存储的数组是一个包含字符串,双精度和布尔值的自定义类对象.如何将所有这三种类型添加到一组?我是否必须将每个单独的对象设置为它们自己的数组,然后在我存储之前将它们单独添加到单独的集合中,或者是否有更简单的方法? (2认同)
  • 致2016年10月之后的读者:此评论已经获得了很多好评,您可以像我一样使用它,但是请停下来,不要这样做。HashSet将丢弃重复的值,因此您的ArrayList将不会相同。此处的详细信息:http://stackoverflow.com/questions/12940663/does-adding-a-duplicate-value-to-a-hashset-hashmap-replace-the-previous-value (2认同)

kc *_*ili 110

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

TinyDB tinydb = new TinyDB(context);
Run Code Online (Sandbox Code Playgroud)

放在

tinydb.putList("MyUsers", mUsersArray);
Run Code Online (Sandbox Code Playgroud)

要得到

tinydb.getList("MyUsers");
Run Code Online (Sandbox Code Playgroud)

UPDATE

可以在此处找到一些有用的示例和疑难解答:Android共享首选项TinyDB putListObject frunction

  • 这是最好的方法.+1来自我的身边 (4认同)
  • 我也是.非常实用! (3认同)
  • 这非常有用!简单而且非常干净的代码! (3认同)
  • @RAWNAKYAZDANI 默认情况下,TinyDB 将为不存在的值返回一个空列表,因此请检查返回列表的大小;如果它是 0,那么您可以将您想要的默认值分配给返回的列表变量。 (2认同)

Har*_*aur 93

保存ArraySharedPreferences:

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();     
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的"黑客".请注意,使用此方法时,始终存在使用未使用的旧值膨胀SharedPreferences的可能性.例如,列表在运行时的大小可能为100,然后大小为50. 50个旧条目将保留在首选项上.一种方法是设置MAX值并清除任何内容. (14认同)
  • @Iraklis确实,但假设您只将这个`ArrayList`存储到`SharedPrefeneces`中,您可以使用`mEdit1.clear()`来避免这种情况. (3认同)
  • 谢谢!如果你介意我问,.remove() 是否有必要的目的?无论如何,首选项不会被覆盖吗? (2认同)

MBy*_*ByD 59

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

  • 使用[toString()](http://developer.android.com/reference/org/json/JSONArray.html#toString()) (4认同)
  • 但是,我如何从SharedPrefs中取回它并将其转换回ArrayList? (3认同)
  • @ryandlf我创建了一个要点:https://gist.github.com/JoachimR/c60aae1bb4b7076332b2 (2认同)

Aym*_*bsi 43

正如@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>();
textList.addAll(data);
String jsonText = gson.toJson(textList);
prefsEditor.putString("key", jsonText);
prefsEditor.apply();
Run Code Online (Sandbox Code Playgroud)

  • 感谢上帝,那是救命稻草。确实很简单。 (3认同)
  • 这个答案应该是向上的。高超!不知道我可以这样使用 Gson。第一次看到这种使用的数组符号。谢谢! (2认同)
  • 要将其转换回List,List <String> textList = Arrays.asList(gson.fromJson(jsonText,String [] .class)); (2认同)
  • 什么是“数据”? (2认同)

sac*_*are 21

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

1.可变声明即

  SharedPreferences shared;
  ArrayList<String> arrPackage;
Run Code Online (Sandbox Code Playgroud)

2.可变初始化即

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

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);
 }
Run Code Online (Sandbox Code Playgroud)

4.使用retriveSharedValue()以下方法检索sharedPreference的值:

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

我希望它对你有所帮助......

  • 一旦添加到集合中,这将从列表中删除所有重复的字符串.可能不是一个想要的功能 (4认同)

Avi*_*vin 13

Android SharedPreferances允许您将内存类型(自API11以来可用的布尔,Float,Int,Long,String和StringSet)保存为内存中的xml文件.

任何解决方案的关键思想是将数据转换为其中一种原始类型.

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

为了使用我的解决方案,您必须添加Google Gson lib.

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

compile 'com.google.code.gson:gson:2.6.2'
Run Code Online (Sandbox Code Playgroud)

保存数据(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();
Run Code Online (Sandbox Code Playgroud)

检索数据(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());
Run Code Online (Sandbox Code Playgroud)


SKT*_*SKT 9

您还可以将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;
        }
Run Code Online (Sandbox Code Playgroud)

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

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


Kri*_*yas 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);
}
Run Code Online (Sandbox Code Playgroud)


小智 8

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

如果要存储 ArrayList 或任何复杂数据。最好的选择是纸库。

添加依赖

implementation 'io.paperdb:paperdb:2.6'
Run Code Online (Sandbox Code Playgroud)

初始化纸张

应该在 Application.onCreate() 中初始化一次:

Paper.init(context);
Run Code Online (Sandbox Code Playgroud)

节省

List<Person> contacts = ...
Paper.book().write("contacts", contacts);
Run Code Online (Sandbox Code Playgroud)

加载数据中

如果存储中不存在对象,则使用默认值。

List<Person> contacts = Paper.book().read("contacts", new ArrayList<>());
Run Code Online (Sandbox Code Playgroud)

干得好。

https://github.com/pilgr/Paper


小智 7

您可以使用 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 !!!

    }
Run Code Online (Sandbox Code Playgroud)

=> 您需要创建函数来从 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);

}
Run Code Online (Sandbox Code Playgroud)

=> 如何调用保存和检索数组列表函数。

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());
Run Code Online (Sandbox Code Playgroud)

=> 不要忘记在应用程序级别的 build.gradle 中添加 gson 库。

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


小智 7

还有 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() }) 
}
Run Code Online (Sandbox Code Playgroud)


Rav*_*raj 7

/**
 *     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);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,最佳答案 (3认同)

Tyl*_*r I 5

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


Khe*_*raj 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();
    }
    
    Run Code Online (Sandbox Code Playgroud)

    }

  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;
    }
    
    Run Code Online (Sandbox Code Playgroud)

Constants.APP_PREFS是要打开的文件的名称;不能包含路径分隔符。