Caching Objects in Android Internal Storage

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

 

Advertisement

20 thoughts on “Caching Objects in Android Internal Storage

  1. 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…

    1. 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.

      1. 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

    1. 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.

  2. I am getting “java.io.NotSerializableException: android.app.Application”

    Any ideas on how I can fix this? Thanks

  3. I am getting a null pointer exception on,
    FileOutputStream fos = context.openFileOutput(key, Context.MODE_PRIVATE);

    Any idea why?
    Thank you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s