I know that SharedPreferences has putString()
, putFloat()
, putLong()
, putInt()
and putBoolean()
. But I need
It is possible to do it without a file.
I'm serializing the information to base64 and like this I'm able to save it as a string in the preferences.
The following code is Serializing a serializable objec to base64 string and vice versa: import android.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSerializerHelper {
static public String objectToString(Serializable object) {
String encoded = null;
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(object);
objectOutputStream.close();
encoded = new String(Base64.encodeToString(byteArrayOutputStream.toByteArray(),0));
} catch (IOException e) {
e.printStackTrace();
}
return encoded;
}
@SuppressWarnings("unchecked")
static public Serializable stringToObject(String string){
byte[] bytes = Base64.decode(string,0);
Serializable object = null;
try {
ObjectInputStream objectInputStream = new ObjectInputStream( new ByteArrayInputStream(bytes) );
object = (Serializable)objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
}
return object;
}
}
2020: If you want to save objects, then it's better to use Proto DataStore instead of SharedPreferences.
It brings great benefits over the “old” SharedPreferences, namely:
And many other perks such as transactional API, which guarantee consistency.
Check out my blog post to see how to implement Proto DataStore easily
The accepted answer is misleading, we can store serializable object into SharedPreferences by using GSON. Read more about it at google-gson.
you can add GSON dependency in Gradle file with:
compile 'com.google.code.gson:gson:2.7'
Here the snippet:
First, create your usual sharedPreferences:
//Creating a shared preference
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);
Saving from serializable object to preference:
Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(YourSerializableObject);
prefsEditor.putString("SerializableObject", json);
prefsEditor.commit();
Get serializable object from preference:
Gson gson = new Gson();
String json = mPrefs.getString("SerializableObject", "");
yourSerializableObject = gson.fromJson(json, YourSerializableObject.class);
We can create an easy to use syntax with Kotlin.
@Throws(JsonIOException::class)
fun Serializable.toJson(): String {
return Gson().toJson(this)
}
@Throws(JsonSyntaxException::class)
fun <T> String.to(type: Class<T>): T where T : Serializable {
return Gson().fromJson(this, type)
}
@Throws(JsonIOException::class)
fun SharedPreferences.Editor.putSerializable(key: String, o: Serializable?) = apply {
putString(key, o?.toJson())
}
@Throws(JsonSyntaxException::class)
fun <T> SharedPreferences.getSerializable(key: String, type: Class<T>): T? where T : Serializable {
return getString(key, null)?.to(type)
}
and then save any Serializable to SharedPreferences
using similar get/put()
Complete gist here Save Serializables in Shared Preferences with Kotlin and GSON
As mentioned in other answers, you might have to consider migration when structure of data class changes. Or atleast would have to change key that you use to store.
In short you cant, try serializing your object to a private file, it amounts to the same thing. sample class below:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import android.app.Activity;
import android.content.Context;
/**
*
* Writes/reads an object to/from a private local file
*
*
*/
public class LocalPersistence {
/**
*
* @param context
* @param object
* @param filename
*/
public static void witeObjectToFile(Context context, Object object, String filename) {
ObjectOutputStream objectOut = null;
try {
FileOutputStream fileOut = context.openFileOutput(filename, Activity.MODE_PRIVATE);
objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(object);
fileOut.getFD().sync();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (objectOut != null) {
try {
objectOut.close();
} catch (IOException e) {
// do nowt
}
}
}
}
/**
*
* @param context
* @param filename
* @return
*/
public static Object readObjectFromFile(Context context, String filename) {
ObjectInputStream objectIn = null;
Object object = null;
try {
FileInputStream fileIn = context.getApplicationContext().openFileInput(filename);
objectIn = new ObjectInputStream(fileIn);
object = objectIn.readObject();
} catch (FileNotFoundException e) {
// Do nothing
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (objectIn != null) {
try {
objectIn.close();
} catch (IOException e) {
// do nowt
}
}
}
return object;
}
}
If you object is simple POJO you can convert object to JSON string and save it in shared preferences with putString().