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

其他回答

您还可以将数组列表转换为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 !!:)

这就是你的完美解决方案。试一试,

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

使用Kotlin,对于简单的数组和列表,你可以这样做:

class MyPrefs(context: Context) {
    val prefs = context.getSharedPreferences("x.y.z.PREFS_FILENAME", 0)
    var listOfFloats: List<Float>
        get() = prefs.getString("listOfFloats", "").split(",").map { it.toFloat() }
        set(value) = prefs.edit().putString("listOfFloats", value.joinToString(",")).apply()
}

然后轻松访问首选项:

MyPrefs(context).listOfFloats = ....
val list = MyPrefs(context).listOfFloats

我使用相同的方式保存和检索字符串,但这里我使用HashSet作为数组列表的中介

使用HashSet保存arrayList到SharedPreferences:

1-我们创建SharedPreferences变量(在数组发生变化的地方)

2 -我们将数组列表转换为HashSet

3 -然后放入stringSet并应用

4 -你在HashSet中获取stringset并重新创建ArrayList来设置HashSet。

public class MainActivity extends AppCompatActivity {
    ArrayList<String> arrayList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SharedPreferences prefs = this.getSharedPreferences("com.example.nec.myapplication", Context.MODE_PRIVATE);

        HashSet<String> set = new HashSet(arrayList);
        prefs.edit().putStringSet("names", set).apply();


        set = (HashSet<String>) prefs.getStringSet("names", null);
        arrayList = new ArrayList(set);

        Log.i("array list", arrayList.toString());
    }
}

请在kotlin中使用这两种方法将数据存储在ArrayList中

fun setDataInArrayList(list: ArrayList<ShopReisterRequest>, key: String, context: Context) {
    val prefs = PreferenceManager.getDefaultSharedPreferences(context)
    val editor = prefs.edit()
    val gson = Gson()
    val json = gson.toJson(list)
    editor.putString(key, json)
    editor.apply()   
}

fun getDataInArrayList(key: String, context: Context): ArrayList<ShopReisterRequest> {
    val prefs = PreferenceManager.getDefaultSharedPreferences(context)
    val gson = Gson()
    val json = prefs.getString(key, null)
    val type = object : TypeToken<ArrayList<ShopReisterRequest>>() {

    }.type
    return gson.fromJson<ArrayList<ShopReisterRequest>>(json, type)
}