Wednesday 15 October 2014

Serialization in Android

We use Java Serialization in our day to day activity for use cases like Sending Object Over Network, Save Object to a file, Saving user preferences in Object etc etc.

Note: We will not be learning about Java Serialization here, visit Serialization_Official to learn about same. I assume you have working knowledge of Serialization to proceed.

What is here so special about Serialization in Android. No doubt you can use serialization the same way you do in Java and deserialize it later on.

But point to remember here is Android application is client side code. Many tools are available in market to convert your dex files to java classes and then decompile your classes to java files.

To safeguard our logic/code from malicious programmers we do use some tools like proguard to obfuscate our code. Now these tools change Class names, variable names and assign some not readable names so that even if somebody gets your java files, either they are of no use OR very difficult to read.

Here comes the problematic part which we are interested in, Serialazation + Proguard. Now assume your class (some sound setting which user has personalised)  name is:

com.example.khanna.SoundSetting

Now during development you serialize and deserialize Object of SoundSetting class and it works perfectly fine.

Suddenly at production you start getting exceptions like ClasNotFoundException while deserializing and you start hitting your head WTF happened and those with prior experience in java Serialization start hitting serialVersionUID and in your next releases you find the same problem occurring sometime and working perfectly sometime.

Lets come to point, when we use tool like proguard, there are certain set of guidelines which these tools follows and convert our java files to some unreadable format. Say named java file "com.example.khanna.SoundSetting" to "com.example.khanna.ae"

Now when you serialize OR deserialize it, ae is the class name used by JVM.

Suppose you release your next version and if you are lucky enough that class name was named again "com.example.khanna.ae" and deserialize will work even after upgrade.

But usually if you have changed something in that package and which makes proguard guidelines to change your file name from "com.example.khanna.SoundSetting" to "com.example.khanna.bd"

Now before upgrade you serialize with ae but after upgrade ae does not exist OR even if it does, it is not the class which you are expecting.

Hope you understand problem !!

Solution to this problem is quite simple, either set your file in proguard settings not to change its name, so "SoundSetting" will always be "SoundSetting" even after obfuscation.
Or Use custom Serialization (readObject and writeObject) where you own the process and serialize and deserialize premitives, so your class name is not required.

happy coding :)