I have an ArrayList with custom objects. Each custom object contains a variety of strings and numbers. I need the array to stick around even if the user leaves the activity and then wants to come back at a later time, however I don't need the array available after the application has been closed completely. I save a lot of other objects this way by using the SharedPreferences but I can't figure out how to save my entire array this way. Is this possible? Maybe SharedPreferences isn't the way to go about this? Is there a simpler method?


当前回答

使用这个自定义类:

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

其他回答

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

Saving String List in shared-preference>> 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(); } } and for getting String List from Shared-preference>> 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; }

这里的常数。APP_PREFS是要打开的文件的名称;不能包含路径分隔符。

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

在API 11之后,SharedPreferences Editor接受set。您可以将List转换为HashSet或类似的东西,并像这样存储它。当你把它读回来时,把它转换成一个数组列表,如果需要的话对它排序,你就可以开始了。

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

你也可以序列化你的数组列表,然后将它保存/读取到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类

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

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

使用Kotlin和GSON:

fun <T> SharedPreferences.writeList(gson: Gson, key: String, data: List<T>) {
    val json = gson.toJson(data)
    edit { putString(key, json) }
}

inline fun <reified T> SharedPreferences.readList(gson: Gson, key: String): List<T> {
    val json = getString(key, "[]") ?: "[]"
    val type = object : TypeToken<List<T>>() {}.type
    
    return try {
        gson.fromJson(json, type)
    } catch(e: JsonSyntaxException) {
        emptyList()
    }
}