Search code examples
androidkotlingenericsparcelablekotlin-reified-type-parameters

Check reified class is Parcelable or Serializable


I have defined an inline method that provides a way to deserialize fragments argument.

And I need to check requested Arg type to choose deserialization method.

inline fun <reified Arg : Any?> Fragment.navArgParser(
    crossinline parcelCreatorProducer: () -> Parcelable.Creator<Arg>
) = NavArgsLazy<Arg?>({
    arguments ?: throw IllegalStateException("Fragment $this has null arguments")
}) {
    when {
        Arg is Parcelable ->   // ISSUE
            NavArgParser.deserializeData<Arg>(it, parcelCreatorProducer.invoke())
        Arg is Serializable ->  // ISSUE
            NavArgParser.deserializeData<Serializable>(it) as Arg
        else ->
            throw IllegalStateException("${Arg::class.java.simpleName} must implement Parcelable or Serializable")
    }
}

How can I check Arg is Parcelable or Serializable?


Solution

  • Arg is not an object so you cannot use is. You should use isAssignableFrom which accepts a class object

    when {
        Parcelable::class.java.isAssignableFrom(Arg::class.java) -> //
        ...
    }
    

    You can also write some extension like:

    inline fun <reified L : Any, reified R : Any> isSubClassOf() = R::class.java.isAssignableFrom(L::class.java)
    
    inline fun <reified L : Any, reified R : Any> isSuperClassOf() = L::class.java.isAssignableFrom(R::class.java)
    

    And use it like

    when{
        isSuperClassOf<Parcelable, Arg> -> //