lundi 23 avril 2018

Android, Kotlin: Creating a GenericTypeIndicator from reflection

So I wrote a class that deserializes a Firebase snapshot into a class. The reason I did this is because I am getting a String object from Firebase which I actually want to instantiate a different class for. This isn't supported by getValue, so I have to do a workaround for it.

Now everything is working, except the Map part. DataSnapshot really wants a GenericTypeIndicator as argument, but since everything will be done dynamically, I don't know how to do this with reflection.

Here is my current code:

fun <T> deserialize(dataSnapshot: DataSnapshot, clazz: Class<T>): T {
    val obj = clazz.newInstance()

    dataSnapshot.children.forEach {
        val field = try {
            clazz.getDeclaredField(it.key)
        } catch(e: NoSuchFieldException) { return@forEach }

        field.isAccessible = true

        when(field.type){
            Translation::class.java ->
                field.set(obj, Translation(it.getValue(String::class.java)!!))
            Map::class.java -> { /* Here we need to do crazy Map GenericTypeIndicator stuff */ }
            else -> field.set(obj, it.getValue(field.type))
        }
    }

    return obj
}


The error I'm getting when I remove the Map case is:

Class java.util.Map has generic type parameters, please use GenericTypeIndicator instead


If I actually use a GenericTypeIndicator with HashMap it will give me the following error:

com.google.firebase.database.DatabaseException: Not a direct subclass of GenericTypeIndicator: class java.lang.Object

Not that I want to do it this way, because this has to be done dynamically eventually.

Now I am at a loss, so any help would be appreciated, mostly because the map differs per object so I can't just have a predefined generic.





Aucun commentaire:

Enregistrer un commentaire