views:

569

answers:

2

Say I have a Java Bean object which is serializable. I want to store it away safely when an Activity goes through onDestroy() on purpose (i.e. onSaveInstanceState() is not called).

I am looking for a way which doesn't involve creating a database and write the object to that (mostly since a) Android's DB API is horrible and b) since databases make application updates a nightmare, because there is no decent support for applying migrations).

I thought about serializing the object to a ByteArrayOutputStream, base64 encode that and write it to a SharedPreferences file as a string. Or is that too far off?

UPDATE

Maybe that serialize-to-string idea wasn't that bad after all, seems to work out pretty well. Here's what I'm doing now:

    public static String objectToString(Serializable object) {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try {
        new ObjectOutputStream(out).writeObject(object);
        byte[] data = out.toByteArray();
        out.close();

        out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out);
        b64.write(data);
        b64.close();
        out.close();

        return new String(out.toByteArray());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

public static Object stringToObject(String encodedObject) {
    try {
        return new ObjectInputStream(new Base64InputStream(
                new ByteArrayInputStream(encodedObject.getBytes()))).readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

in onDestroy() I can then simply write the Base64 string to a preference file, where it's safe until I read it again during the next activity launch. It's a lot faster than I expected and unless your beans carry huge amounts of data, it works pretty well. And even better, you don't have to maintain a DB schema.

Still, I'm curious about how others do this.

+2  A: 

I am looking for a way which doesn't involve creating a database and write the object to that (mostly since a) Android's DB API is horrible and b) since databases make application updates a nightmare, because there is no decent support for applying migrations).

Android's API is actually fairly reasonable, mostly because it's a thin wrapper over the SQLite API, and the SQLite API is fairly reasonable for an embedded database. Moreover, Android does provide assistance for schema upgrades on app upgrades, via SQLiteOpenHelper.

It's a lot faster than I expected and unless your beans carry huge amounts of data, it works pretty well.

I have heard of many more developers running away screaming from serialization than I have heard of people having long term success with it. Just within the past few days, here on SO #android, I had an exchange with somebody trying desperately to rip serialization out of his app by the roots.

And even better, you don't have to maintain a DB schema.

Oh yes you do. What do you think is going to happen when you update your application and your class is modified? Doing the bookkeeping to figure out how to deserialize old versions of the class from a new version of a class is a chore and is one of the reasons developers abandon serialization. Also, do not forget that serialization is not transactional, whereas SQLite is.

CommonsWare
Sorry, I don't agree at all. Having to maintain a database to store a simple object temporarily seems more than just a little excessive to me. Plus, I am aware of SQLiteOpenHelper and all its limitations, and I found DB migrations to be a major pain in the back.Plus, there is NO maintenance required here, since I can simply clear() the editor before storing an object, regardless of its structure. Think document based database, there is no schema. With a DB, I would have to DROP TABLE whenever the model changes.
Matthias
To each their own.
CommonsWare
+5  A: 

You can serialize an object directly to a new file, without having to base-64 encode anything. An example is here.

I think it would be simpler to just serialize your object to a separate file, rather than base-64 encoding it and putting it in the preferences file. You could write your serialized file in the directory returned by getDataDirectory().

That said, I agree that serialization can be a pain, but you'll end up having similar problems whether serializing to a file or to the DB.

Kevin Tighe
thanks, good point.
Matthias
Hi Kevin, your "here" link is broken, can you update the link, so that we could take a look at it ? thanks.
Hubert
Whoops, fixed: http://java.sun.com/developer/technicalArticles/Programming/serialization/
Kevin Tighe