Room - Provided Type Converters explained
Published: 2020-10-14 18:19:48

This blog post explains the newly developed Room’s feature called Provided Type Converters. It also contains a brief description of the process of contributing to AndroidX via GitHub.

## What is a Type Converter?
To access complex (non-primitive) data using Room, a [Type Converter](https://developer.android.com/training/data-storage/room/referencing-data) has to be used. A Type Converter is a method annotated with `@TypeConverter`. It must receive exactly one parameter and have a non-void return type. Room needs to be able to call it so such method must also meet one of these conditions:
* must be static
* or must be declared inside [Kotlin object](https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#object-declarations)
* or must be declared inside a class which has a no-argument public constructor.

It means that there is no way to pass a dependency to a class that contains `@TypeConverter` annotated methods. An author of this [issue](https://issuetracker.google.com/u/0/issues/121067210) mentions passing Json serializer to a Type Converter as an example. The only option to do it was to use a global state. But now there is a new, better way.

## Provided Type Converter
Room [2.3.0-alpha03](https://developer.android.com/jetpack/androidx/releases/room#2.3.0-alpha03) contains a new feature called Provided Type Converters which is a solution to the aforementioned problem. Room checks at compile time if it has enough information to invoke a method annotated with `@TypeConverter` . If it’s not possible then the compilation will fail. The idea of Provided Type Converters is that it gives a developer the possibility to take control over instantiation of a Type Converter and treat it like any other class. It’s achieved by annotating a Type Converter Class with `@ ProvidedTypeConverter` which tells Room to skip some of the compile time checks it performs for converters without this annotation. A developer has to manually add an instance of such a converter to Room by calling a new `addTypeConverter` method on a `Room.databaseBuilder`. Otherwise Room won’t be able to use the converter and will throw an exception at runtime.

Here is a short example of passing a dependency to a Type Converter using Provided Type Converter feature:

```kotlin
// Annotate converter to skip compile time validation
@ProvidedTypeConverter
class ExampleConverter(private val dependency: Foo) {
    @TypeConverter
    fun fromString(value: String?): Bar {
        return dependency.toBar(value)
    }

    @TypeConverter
    fun barToString(bar: Bar?): String {
        return dependency.toString(bar)
    }
}

// Create or inject ExampleConverter instance and 
// pass it to RoomDatabase builder
val exampleConverterInstance = ExampleConverter(Foo());

db = Room.databaseBuilder(...)
        .addTypeConverter(exampleConverterInstance)
        .build();
```


## Contributing to AndroidX
Some time ago AndroidX was pushed to [GitHub](https://github.com/androidx/androidx) which means that anyone can contribute without pulling AOSP and learning its tooling. At the moment of writing this post six projects are open for contributions: Room, Paging, Work Manager, Fragment, Activity and Navigation. There is a bug bounty [hotlist](http://goo.gle/androidx-bug-bounty) on issue tracker. It contains a list of bugs and features that can be picked up by external contributors. The process looks like this:
1. Reading [Contribution Guide](https://github.com/androidx/androidx/blob/androidx-master-dev/CONTRIBUTING.md).
2. Finding a ticket in a bug bounty hotlist that seems especially interesting.
3. Commenting on that ticket and volunteering to take care of it.
4. Waiting for the reply and starting investigating it in the meantime.
5. If it’s a feature, the next step will most probably be writing a design doc which explains an idea. [Here](https://docs.google.com/document/d/1nmXZUsSlH6WWsT3Duxnkd4LcAPZGcyVCwJe5scnh7HU/edit#heading=h.9pamohduoypt) is mine for Provided Type Converters feature.
6. If it’s a bug, simply starting to code.
7. Creating a PR on GitHub and waiting for review.

In case of any blockers or if it’s just not clear where to start, maintainers are there to help. No need to be afraid to reach out to them as they are very helpful and responsive!

I learned a lot during the contribution process and it was a pleasure to work on it. It was also an eye-opening experience for me because I was able to see how much care is being put into designing AndroidX APIs. I haven’t seen Room code before, had very little experience with annotation processing, and yet I managed to do it so if I can do it, you can do it too! The more external contributions, the more projects will be opened for contributing.

I wouldn’t be able to do it without [Yigit](https://twitter.com/yigitboyar) and [Dany](https://twitter.com/danyaguacate) – thank you for the support and for proofreading this post!