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?


当前回答

你可以从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);
    }
}

其他回答

    public  void saveUserName(Context con,String username)
    {
        try
        {
            usernameSharedPreferences= PreferenceManager.getDefaultSharedPreferences(con);
            usernameEditor = usernameSharedPreferences.edit();
            usernameEditor.putInt(PREFS_KEY_SIZE,(USERNAME.size()+1)); 
            int size=USERNAME.size();//USERNAME is arrayList
            usernameEditor.putString(PREFS_KEY_USERNAME+size,username);
            usernameEditor.commit();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

    }
    public void loadUserName(Context con)
    {  
        try
        {
            usernameSharedPreferences= PreferenceManager.getDefaultSharedPreferences(con);
            size=usernameSharedPreferences.getInt(PREFS_KEY_SIZE,size);
            USERNAME.clear();
            for(int i=0;i<size;i++)
            { 
                String username1="";
                username1=usernameSharedPreferences.getString(PREFS_KEY_USERNAME+i,username1);
                USERNAME.add(username1);
            }
            usernameArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, USERNAME);
            username.setAdapter(usernameArrayAdapter);
            username.setThreshold(0);

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

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

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

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

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

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

但是一旦应用程序关闭,数据就不应该被保存。因此,我觉得使用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。最好的部分是一旦应用程序关闭,我们不必担心数据被存储。:)

使用这个对象——> TinyDB——Android-Shared-Preferences-Turbo非常简单。

TinyDB tinydb = new TinyDB(context);

tinydb.putList("MyUsers", mUsersArray);

得到

tinydb.getList("MyUsers");

更新

一些有用的例子和故障排除可以在这里找到:Android共享偏好TinyDB putListObject函数

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