Search code examples
androidandroid-architecture-navigationkotlin-multiplatformkotlinx.serializationandroid-safe-args

How to use Navigation Safe Args with Kotlinx serializable data


I'm trying to use Navigation Safe Args with Kotlinx @Serializable types, but I keep getting the same issue during run-time when I pass the serializable data:

Caused by: java.lang.IllegalArgumentException: com.example.serializablesafeargsnavigation.shared.Model.SerializableModel is not Serializable or Parcelable.

In my nav_graph.xml I have the following:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/firstFragment">

    <fragment
        android:id="@+id/firstFragment"
        android:name="com.example.serializablesafeargsnavigation.androidApp.FirstFragment"
        android:label="FirstFragment" >
        <action
            android:id="@+id/action_firstFragment_to_secondFragment"
            app:destination="@id/secondFragment" />
    </fragment>

    <fragment
        android:id="@+id/secondFragment"
        android:name="com.example.serializablesafeargsnavigation.androidApp.SecondFragment"
        android:label="SecondFragment">
        <argument
            android:name="arg"
            app:argType="com.example.serializablesafeargsnavigation.shared.Model.SerializableModel" />
    </fragment>
</navigation>

My SerializableModel looks like this:

@Serializable
data class SerializableModel(
    @SerialName("some_value")
    val someValue: String
)

Has anybody found a workaround to make this work with Safe Args. It works if you pass a Bundle with the navigate API, but I would like to use Safe Args if possible.

Versions I'm using

  • plugin.serialization: 1.4.21
  • navigation-safe-args-gradle-plugin: 2.3.2
  • androidx.navigation:navigation-ui-ktx: 2.3.2
  • androidx.navigation:navigation-fragment-ktx: 2.3.2
  • kotlinx-serialization-core: 1.0.1

Thanks in advance!


Solution

  • If your model is in the shared module, probably you won't be able to use jvm and android dependencies.

    You can create your own parcelize expect/actual abstraction or you could use moko-parcelize, which essentially does the same