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?


当前回答

在SharedPreferences中使用getStringSet和putStringSet非常简单,但在我的情况下,我必须在向Set中添加任何东西之前复制Set对象。否则,Set将不会被保存,如果我的应用程序是强制关闭。可能是因为下面API中的注释。(如果应用程序被返回按钮关闭,则保存)。

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

其他回答

以上答案都是正确的。:)我自己就用了其中一个。然而,当我读到这个问题时,我发现这篇文章实际上是在谈论一个不同的场景,如果我没有弄错的话。

"我需要这个数组一直存在即使用户离开了活动然后想要在稍后的时间回来"

实际上,他希望数据一直存储到应用程序打开为止,而不管用户在应用程序中更换屏幕。

“然而,我不需要阵列可用后,应用程序已完全关闭”

但是一旦应用程序关闭,数据就不应该被保存。因此,我觉得使用SharedPreferences并不是最优的方式。

对于这个需求,我们可以创建一个扩展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。最好的部分是一旦应用程序关闭,我们不必担心数据被存储。:)

您还可以将数组列表转换为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方法将数组列表转换为字符串后保存它,并使用convertToArray方法检索字符串并将其转换为数组

在API 11之后,你可以直接保存设置到SharedPreferences !!:)

从SharedPreference中保存和检索ArrayList

 public static void addToPreference(String id,Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.MyPreference, Context.MODE_PRIVATE);
        ArrayList<String> list = getListFromPreference(context);
        if (!list.contains(id)) {
            list.add(id);
            SharedPreferences.Editor edit = sharedPreferences.edit();
            Set<String> set = new HashSet<>();
            set.addAll(list);
            edit.putStringSet(Constant.LIST, set);
            edit.commit();

        }
    }
    public static ArrayList<String> getListFromPreference(Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.MyPreference, Context.MODE_PRIVATE);
        Set<String> set = sharedPreferences.getStringSet(Constant.LIST, null);
        ArrayList<String> list = new ArrayList<>();
        if (set != null) {
            list = new ArrayList<>(set);
        }
        return list;
    }

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

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

你可以使用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”