Skip to content Skip to sidebar Skip to footer

Store A Collection Of Objects In Sharedpreferences

I am working on a developing a utility class for storing data in SharedPreferences. Till now, I was able to make a generic function to store and retrieve String, int and boolean. I

Solution 1:

There is no direct way but two indirect ways:

1. Use GSON.

publicstaticbooleansaveObjectToPrefs(String prefKey, Objectobject, Context context) {
    SharedPreferences.Editor editor = getSharedPreferences(context).edit();
    try {
        Gson gson = newGson();
        String json = gson.toJson(object);
        editor.putString(prefKey, json);
        editor.apply();
        returntrue;
    } catch (Exception e) {
         e.printStackTrace();
         returnfalse;
    }
}

The generic here should implement Serializable interface.

To retrieve object create a method like this:

publicstatic <T> T getObjectFromPrefs(String prefKey, Class<T> type, Context context) {
    String json = getSharedPreferences(context).getString(prefKey, null);
    if (json != null) {
        try {
            Gson gson = newGson();
            T result = gson.fromJson(json, type);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    returnnull;
}

and you can call this method like for collections:

PrefUtils.getObjectFromPrefsByType(PREF_KEY_USERS, new TypeToken<ArrayList<User>>() {
    }.getType(), context);

for normal objects you can do:

PrefUtils.getObjectFromPrefsByType(PREF_KEY_USER, User.class, context);

2. Write a custom Serializer and Deserializer

I usually prefer this method as I don't have to include a library for it.

Here is the custom serializer/deserializer implemetation:

publicclassObjectSerializer {


publicstatic String serialize(Serializable obj){
    if (obj == null) return"";
    try {
        ByteArrayOutputStreamserialObj=newByteArrayOutputStream();
        ObjectOutputStreamobjStream=newObjectOutputStream(serialObj);
        objStream.writeObject(obj);
        objStream.close();
        return encodeBytes(serialObj.toByteArray());

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

}

publicstatic Object deserialize(String str)  {
    if (str == null || str.length() == 0) returnnull;
    try {
        ByteArrayInputStreamserialObj=newByteArrayInputStream(decodeBytes(str));
        ObjectInputStreamobjStream=newObjectInputStream(serialObj);
        return objStream.readObject();
    } catch (Exception e) {
        e.printStackTrace();
        returnnull;
    }
}

publicstatic String encodeBytes(byte[] bytes) {
    StringBuilderstrBuf=newStringBuilder();
    for (Byte b: bytes) {
        strBuf.append((char) (((b >> 4) & 0xF) + ((int) 'a')));
        strBuf.append((char) (((b) & 0xF) + ((int) 'a')));
    }
    return strBuf.toString();
}

publicstaticbyte[] decodeBytes(String str) {
    byte[] bytes = newbyte[str.length() / 2];
    for (inti=0; i < str.length(); i+=2) {
        charc= str.charAt(i);
        bytes[i/2] = (byte) ((c - 'a') << 4);
        c = str.charAt(i+1);
        bytes[i/2] += (c - 'a');
    }
    return bytes;
    }
}

Now, inside PrefUtils.java you can have method like:

public static void saveUser(Context context, User user) {
    getSharedPreferences(context)
                        .edit()
                        .putString(PREF_KEY_USER, ObjectSerializer.serialize(user))
                        .apply();
}

To retrieve the object you can use following method:

publicstaticUsergetUser(Context context) {
    String serializedUser = getSharedPreferences(context).getString(PREF_KEY_USER, "");
    return ((User) ObjectSerializer.deserialize(serializedUser));
}

Again User class has to be Serializable. Also, don't forgot explicit casting as ObjectSerializer.deserialize(String str) method returns an object of type Object and not the class you serialized. Also, take care of null values.

Solution 2:

Is there a generic way to store and retrieve a collection of objects?

No, as of now, there is no generic way. You can use the following methods:

  • putBoolean(String key, boolean value)

  • putFloat(String key, float value)

  • putInt(String key, int value)

  • putLong(String key, long value)

  • putString(String key, String value)

  • putStringSet(String key, Set values)

That's all you can do with SharedPreferences. If you want to store anything generic, you can try to serialize your object and put it as a String to SharedPreferences. About Serialization

Solution 3:

I've spend a lot of time playing with that question. Since I work with an iPhone guy how can save anyObjects (what is that??) :)

I have settled on 2 solutions. If im storing a cache that have a short term usage, I wrap an abitrary object as a Parceable with Parceler (https://github.com/johncarl81/parceler).

If I need persistent data that the app uses to save user actions, I wrap any abitrary object with GSON, and save it to the disk. That way I can still update the app with more fields, and still use the data that comes from the GSON object, since it handles null value fields. (https://github.com/google/gson)

Post a Comment for "Store A Collection Of Objects In Sharedpreferences"