Is it possible to use a custom Serializable
object as a fragment argument when using deep links?
I've tried the following - in my navigation graph XML file I've added following lines:
<fragment
android:id="@+id/eventFragment"
android:name="com.myapp.EventFragment"
android:label="EventFragment">
<argument
android:name="event"
app:argType="com.myapp.EventId" />
<deepLink app:uri="myapp://event/{event}" />
</fragment>
Where EventId
is a serializable data class:
data class EventId(val value: Long) : Serializable
Then, when I'm trying to run my application with an URL myapp://event/4002
, the following exception is thrown:
Caused by: java.lang.UnsupportedOperationException: Serializables don't support default values.
at androidx.navigation.NavType$SerializableType.parseValue(NavType.java:834)
at androidx.navigation.NavType$SerializableType.parseValue(NavType.java:787)
at androidx.navigation.NavType.parseAndPut(NavType.java:96)
at androidx.navigation.NavDeepLink.getMatchingArguments(NavDeepLink.java:99)
at androidx.navigation.NavDestination.matchDeepLink(NavDestination.java:366)
at androidx.navigation.NavGraph.matchDeepLink(NavGraph.java:79)
at androidx.navigation.NavController.handleDeepLink(NavController.java:540)
at androidx.navigation.NavController.onGraphCreated(NavController.java:499)
at androidx.navigation.NavController.setGraph(NavController.java:460)
at androidx.navigation.NavController.setGraph(NavController.java:425)
at androidx.navigation.NavController.setGraph(NavController.java:407)
at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.java:236)
Replacing type with long
(app:argType="long"
) solves the issue - there is no exception and everything works as expected.
It seems like the navigation library does not know how to convert the raw value from the URL to my EventId
class. Is it possible to somehow register an adapter which knows how to convert it? Or maybe there is another solution?
As far as I am aware, you only have one other alternative to what you have done: Parcelable.
I think it will be sufficient in this case, but I am not sure, but even if it doesn't, this will be a good recommendation for any future Android development when you for example need to send data between Activities or fragments.
Especially as I can see you are using Kotlin, which has a helper method for implementing it correctly, see: Parcelize.
With it, your data class would simply look like this:
@Parcelize
data class EventId(val value: Long) : Parcelable
Side note: Usage of the Serializable interface is discouraged for various reasons. From the book Effective Java written by Joshua Bloch who worked on Java for a long time:
Item 85: Prefer alternatives to Java serialization
If you still have to use Serializable, the book will cover the necessary details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With