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?


当前回答

以防有人需要保存列表的列表,即list < list < String > >。我是这样做的:

序列化

Gson gson = new Gson();
// Save the size of the array
sharedPreferencesEditor.putInt("ArraySize", myArray.size());

for (int i=0; i<myArray.size(); i++) {
  String key = "Array"+i;
  String json = gson.toJson(myArray.get(i));
  sharedPreferencesEditor.putString(key, json);
}

sharedPreferencesEditor.commit();

反序列化

// Get the size of the array to be deserialized. In my case, the default number should be 3
int arraySize = sharedPreferences.getInt("ArraySize",3);

myArray = new ArrayList<List<String>>();

for (int i=0; i<arraySize; i++) {
  String key = "Array"+i;
  String json = sharedPreferences.getString(key, null);
  List<String> arrayTemp= gson.fromJson(json, List.class);
  myArray.add(arrayTemp);
}

// My array may also include components with empty strings. 
// Gson makes them null values and it is not possible 
// to deserialize them as empty strings. 
// The following takes care of that:

for (int i=0; i<myArray.size();i++) {
   if (myArray.get(i) == null) {
      List<String> emptyComponent = new ArrayList<String>() {
         { add(""); }
      };
      myArray.set(i,emptyComponent);
   }
}

其他回答

在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类

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

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

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

使用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()
    }
}

Android sharedpreferences允许您将基本类型(Boolean, Float, Int, Long, String和StringSet,自API11以来可用)作为xml文件保存在内存中。

任何解决方案的关键思想都是将数据转换为这些基本类型之一。

我个人喜欢将my list转换为json格式,然后将其保存为SharedPreferences值中的字符串。

为了使用我的解决方案,你必须添加谷歌gsonlib。

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