What is TypeConverter in Room? How to use it properly

As Android developers, we should be thankful for the existence of the Room persistence library. Before Room, we had to write tons of lines of code to make SQLite work. It helped us clean those boilerplate codes, as well as making working with SQLite more fun and simple. It provides many functionalities, including conversion between primitive and boxed types, but it doesn’t support object references. Think about the few primitive types that are coming into your mind, such as int, long, float, and char, etc. But sometimes, we need a custom data type whose value you would like to store into a single database column. I’m talking about custom data types such as Date, Bitmap, etc. As I said earlier, this object reference is not possible in Room at the moment. But we don’t need to worry. Here comes TypeConverter for our rescue, which can convert a custom class to and from a known type which Room can persist.

Let’s get our hands dirty.

This is our POJO class called Run,

@Entity(tableName = "running_table")
data class Run(
var img: Bitmap? = null,
var timestamp: Long = 0L,
var avgSpeedInKMH: Float = 0f,
var distanceInMeters: Int = 0,
var timeInMillis: Long = 0L,
var caloriesBurned: Int = 0
) {

@PrimaryKey(autoGenerate = true)
var id: Int? = 0

}

Look at the first item in the POJO.

var img: Bitmap? = null

It’s a custom object and will not fit into any of the primitive data types we talked about earlier.

And this is our Dao class,

@Dao
interface RunDAO {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertRun(run: Run)

@Delete
suspend fun deleteRun(run: Run)

@Query("SELECT * FROM running_table ORDER BY timestamp DESC")
fun getAllRunsSortedByDate(): LiveData<List<Run>>

}

You can see that we are running a query to get all the runs sorted by date, and it’s returning a list of Run, and it will include our custom data type, img, which is a Bitmap. And if you try running this code, you will get the following error message.

As the error message suggesting us, let us try creating a Type converter now and see if this error is showing again.

I’m going to create a new class called Converters.

class Converters {

@TypeConverter
fun toBitmap(bytes: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}

@TypeConverter
fun fromBitmap(bmp: Bitmap): ByteArray {
val outputStream = ByteArrayOutputStream()
bmp.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
return outputStream.toByteArray()
}
}

It has two functions.

  1. fromBitmap: This function will take a Bitmap as a parameter and returns a ByteArray. A ByteArray is nothing but an array of bytes. As you have correctly guessed, a byte is a primitive type which is known for Room.
  2. toBitmap: This function will take a ByteArray as a parameter and returns a Bitmap. As you have correctly guessed again, it is our custom object in this case.

Also note that we have used an annotation called, “@TypeConverter” before the starting of each function.

Next, we have to make a small change in our database class.

@Database(
entities = [Run::class],
version = 1,

)
@TypeConverters(Converters::class)
abstract class RunningDatabase : RoomDatabase() {

abstract fun getRunDao(): RunDAO
}

Take a look into this line,

@TypeConverters(Converters::class)

We have added the “@TypeConverters” annotation to our database class so that Room can use the converter we have defined earlier to convert our Bitmap to ByteArray and vice versa. You can put as many converters as you want.

Now try running that query again and see if there are any more errors popping up.

@Query("SELECT * FROM running_table ORDER BY timestamp DESC")
fun getAllRunsSortedByDate(): LiveData<List<Run>>

If you have followed the above steps correctly, it will work perfectly. And congrats. You have learned how to use TypeConverter. For more information about TypeConverter in Room, please check out the official documentation from the Android developers. I have learned more about TypeConverter by watching this guy’s(Philipp Lackner) YouTube channel. He talks in-depth about Android development and Kotlin.

Lastly, if you liked reading this post and genuinely thinking it helped you, please give a clap and share it among your fellow developer friends. Thank you. Be safe.

Senior Software Engineer @ BestDoc. I love to read and write.