Quick Guide to Android Serialization


Note: This is for an early version of Android and might not work on recent versions.

What this will hopefully cover

Every now and then I write a utility class that proves to be halfway useful. Such is the case for something I called SerializationHelper which I've now used in 4-5 different Android applications. This guide is basically the source of that class with a few comments about how it works. When we're all done you should have learned:

1) How to check whether and Android device has an SD card mounted.

2) How to store an object to any directory on the SD card.

3) How to retrieve a stored object.


Check if SD card is mounted

Before you can serialize an object you have to make sure there's some place to write it. We do that by calling Environment.getExternalStorageState() and crossing our fingers that it returns Environment.MEDIA_MOUNTED. If it returns something else we'll do some extremely granular error logging to make our debugging efforts a tad easier. If you'd prefer you could throw an exception with a description of the media state.


  public static boolean checkMediaState(){
    String state=Environment.getExternalStorageState();
    if(state.equals(Environment.MEDIA_MOUNTED)){
      return(true);
    }
    if(Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is read-only. [state=MEDIA_MOUNTED_READ_ONLY]");
    }else if(Environment.MEDIA_CHECKING.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is being disk-checked. [state=MEDIA_CHECKING]");
    }else if(Environment.MEDIA_BAD_REMOVAL.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card was removed before it was unmounted. [state=MEDIA_BAD_REMOVAL]");
    }else if(Environment.MEDIA_NOFS.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is blank or is using an unsupported filesystem. [state=MEDIA_NOFS]");
    }else if(Environment.MEDIA_REMOVED.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is missing. [state=MEDIA_REMOVED]");
    }else if(Environment.MEDIA_SHARED.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is shared. If you are connected to a PC via USB please disconnect and try again. [state=MEDIA_SHARED]");
    }else if(Environment.MEDIA_UNMOUNTABLE.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is present but cannot be mounted. [state=MEDIA_UNMOUNTABLE]");
    }else if(Environment.MEDIA_UNMOUNTED.equals(state)){
      Log.e("your-app-tag","checkMediaState - SD card is not mounted. [state=MEDIA_UNMOUNTED]");
    }else{
      Log.e("your-app-tag","checkMediaState - Unknown media state. [state="+state+"]");
    }
    return(false);
  }

Serializing an object

I'll assume you already know to implement Serializable in the class you want to store. To make life simple this method just takes an object and the name of the destination file to create. The method then checks if the destination path exists, creates it if it doesn't, opens file & object output streams, and writes the file. It catches a generic Exception because there are several named Exceptions that can be thrown along the way. If you prefer to catch individual named Exceptions go ahead and make that change. Oh, and replace "your-app-directory" with whatever you feel like or move it to a configuration file.


  public static boolean serializeObject(Serializable sobj,String destinationFileName){
    try{
      if(checkMediaState()){
        File dir=new File(Environment.getExternalStorageDirectory().getPath()+"/your-app-directory");
        if(!dir.exists()){
          dir.mkdir();
        }
        File f=new File(dir.getPath()+"/"+destinationFileName);
        if(!f.exists()){
          f.createNewFile();
        }
        FileOutputStream fout=new FileOutputStream(f);
        ObjectOutputStream oout=new ObjectOutputStream(fout);
        oout.writeObject(sobj);
        oout.close();
        return(true);
      }else{
        return(false);
      }
    }catch(Exception x){
      Log.e("your-app-tag","serializeObject",x);
      if(sobj!=null){
        Log.e("your-app-tag","sobj="+sobj.toString());
      }
      return(false);
    }
  }

Reading an object

Reading an object is pretty straightforward - check if the SD card is present, create the input streams, and return the object. The previous comments about error handling apply here too.


 public static Object readObject(String sourceFileName){
  Object sobj=null;
  try{
   if(checkMediaState()){
    File dir=new File(Environment.getExternalStorageDirectory().getPath()+"/your-app-directory");
    if(!dir.exists()){
     throw(new Exception(dir.getPath()+" does not exist"));
    }
    FileInputStream fin=new FileInputStream(dir.getPath()+"/"+sourceFileName);
    ObjectInputStream oin=new ObjectInputStream(fin);
    sobj=oin.readObject();
   }
  }catch(Exception x){
   Log.e("your-app-tag","readObject",x);
   if(sobj!=null){
    Log.e("your-app-tag","sobj="+sobj.toString());
   }
  }
  return(sobj);
 }


Related