Recently, I have been working on a project where I need to store sealed classes data inside the Room Persistence using the Kotlinx Serialization library. We all know that Room only supports primitives types for storage. I struggle for almost two days just store the sealed classes using the Kotlinx Serialization library.
So, in this article, I’ll walk through you how to serialize and deserialize the sealed classes using the Kotlinx Serialization library.
To find out the basics of Kotlinx Serialization check out the following article.
Kotlinx Serialization and Room Persistence requires us to add some more stuff to our application module build.gradle file. We start by adding the following dependencies.
We also need to add a classpath for Kotlinx Serialization library inside the top-level build.gradle file inside the buildScript->dependencies section.
Structure of sealed class
The structure of my sealed class is pretty simple. I have one top-level sealed class and inside that class, there are several inheritance hierarchies. First, let’s see the structure.
In order to do serializing for sealed classes, we need to annotate our classes with @Serializable annotation and all the inner classes inside it.
Now let’s say I have this following class which holds the instance of my AnsweredContent sealed class.
The @Polymorphic serialization annotation mostly used on sealed, abstract classes, and on interfaces as well.
Here is the definition of @Polymorphic annotation.
This annotation is applied to interfaces and serializable abstract classes and can be applied to open classes as well. Does not affect sealed classes because they are be serialized with sub-classes automatically.
Now to actually use this in action and convert the AnsweredContentHolder into JSON and back to object. We need to write a custom serializer for this.
Writing custom serializer
For the sake of simplicity, I have created a BaseSerializer<T> and define the generics
toTString method there. Have each custom serializer extends the BaseSerializer and add methods specific to each of them.
And here is the implementation class of our generic serializer.
Here is the step-by-step implementation of above code.
- If you remembered our AnsweredContent class has the @Polymorphic annotation on it. So, for the correct serialization and deserialization, we need to tell KSerializer how to do serialize and deserialize the AnsweredContent using the SerializersModule.
- Supply the serializer for AnsweredContentHolder because this class holds the reference of our AnsweredContent instance.
- Returning the instance of Json by passing the sealedModule.
- Parse the json string into AnsweredContentHolder class instance.
- Convert the object into the string using the StringFormat.
Testing kotlinx serialization and deserialization with Object
In order to test the serialization and deserialization, we just need to get the instance of AnsweredContentSerializer and pass the valid parameter to its function. Let’s see the example.
Testing kotlinx serialization and deserialization with Collection
Now let’s say if I need to serialize and deserialize the list of AnsweredContentHolder using our generic serializer. So, for that, we need to update our AnsweredContentSerializer and pass the List<AnsweredContentHolder> instead of simple class for generic.
The only noticeable thing in the above code is, you see we’re returning
KSerializer<List<AnsweredContentHolder>> instead of simple KSerializer.
And here’s how to convert the collection into string and back to collection.
Alright, guys, this was my understanding of how to serialize and deserialize the sealed classes through Kotlinx Serialization library. If you any queries or suggestion on improving the above example please let me know in the comments section.
Thank you for being here and keep reading…