Android provides several options for persisting application data, such as SQLite Databases, SharedPreferences, internal and external storage.
In this post we’ll take a look how we can use the internal storage to persist application data. By default, files saved to internal storage are private to the application and they cannot be accessed by other applications. When the application is uninstalled, the files are removed.
To create and write a file to internal storage, openFileInput(); should be used. This opens a private file associated with the Context’s application package for writing. If the file does not already exits, then it is first created.
openFileInput() returns a FileInputStream, and we could use its write() method, which accepts a byte array as argument, to write the data. However, in the below example we will wrap the FileInputStream into an ObjectOutputStream which provides 2 convenient methods for writing and reading objects: writeObject() and readObject().
So, lets pretend that we need to save a List of some objects. The model class of our object looks like this:
public class Entry implements Serializable{ private String name; public Entry(String name) { this.name = name; } public String getName() { return name; } }
Make sure that the model class implements Serializable, otherwise you may get a java.io.NotSerializableException when attempting to write the object on internal storage.
Below is the utility class that provides 2 methods, one for storing objects to internal storage, and another for retrieving objects from internal storage.
public final class InternalStorage{ private InternalStorage() {} public static void writeObject(Context context, String key, Object object) throws IOException { FileOutputStream fos = context.openFileOutput(key, Context.MODE_PRIVATE); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(object); oos.close(); fos.close(); } public static Object readObject(Context context, String key) throws IOException, ClassNotFoundException { FileInputStream fis = context.openFileInput(key); ObjectInputStream ois = new ObjectInputStream(fis); Object object = ois.readObject(); return object; } }
An this is how InternalStorage class can be used to persist and retrieve data from internal storage.
// The list that should be saved to internal storage. List<Entry> entries = new ArrayList<Entry>(); entries.add(new Entry("House")); entries.add(new Entry("Car")); entries.add(new Entry("Job")); try { // Save the list of entries to internal storage InternalStorage.writeObject(this, KEY, entries); // Retrieve the list from internal storage List<Entry> cachedEntries = (List<Entry>) InternalStorage.readObject(this, KEY); // Display the items from the list retrieved. for (Entry entry : cachedEntries) { Log.d(TAG, entry.getName()); } } catch (IOException e) { Log.e(TAG, e.getMessage()); } catch (ClassNotFoundException e) { Log.e(TAG, e.getMessage()); }
Forgive my ignorance, but is there any way that files saved to internal storage can persist even after the app is uninstalled? For example, if you think that data will be needed if the user reinstalls the app…
In this case do not save the files on internal storage, save them on external storage.
How to delete the object from internal storage. Plz need help.
What is key here ? What is the File Type in which the objects are stored.?
They KEY could be any string, just make sure you use the same key for writing/reading the file. The file type is irrelevant here, it could have no file extension at all, but that is not important in this case.
How do we remove internal storage object from memory on logout from the app. Actually i am using this for one time login into my app , but if user click at logout button it should delete the object to show login form again…. can you please help…how do i achieve this task …. thanks in advance
Is there a way to set expiration on the cached object?
One idea would be to add one more field to the cached object that will store the time when the object was created. Then every time on application startup retrieve the cached objects and compare each against an expiration interval, if the allowed cached time expired, delete the object.
can u provide download link?
I am getting “java.io.NotSerializableException: android.app.Application”
Any ideas on how I can fix this? Thanks
Make sure that your class, as well as any members of it, are Serializable.
your Entry class should implement Serializable
Thanks , it works for me.
I am getting a null pointer exception on,
FileOutputStream fos = context.openFileOutput(key, Context.MODE_PRIVATE);
Any idea why?
Thank you
The context or the key might be null….. run in debug mode and set a breakpoint to that line to get more info.
Neat tutorial! Thanks.
tanks bro,
Great tutorial! I am just wondering, is it possible to delete the cache once the view have been destroyed? Thanks!
Its override while adding new one
thanks…
it work for me