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?
当前回答
使用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()
}
}
其他回答
在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类型对象转换回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();
/**
* 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)
}
你可以从FacebookSDK的SharedPreferencesTokenCache类中引用serializeKey()和deserializeKey()函数。它将supportedType转换为JSON对象,并将JSON字符串存储为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);
}
}
你可以使用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”
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用