Voyager by default expect that it screens can be stored inside a Bundle. This means both Java Serializable and Parcelable are supported. By default all Voyager Screen is Java Serializable this means that Screen can be restored if all parameters are Java Serializable.
Java Serializable
// ✔️ DOdataclassPost(/*...*/) : SerializabledataclassValidScreen(val userId: UUID, // Built-in serializable typesval post: Post// Your own serializable types) : Screen {// ...}// 🚫 DON'TclassPost(/*...*/)dataclassInvalidScreen(val context: Context, // Built-in non-serializable typesval post: Post, // Your own non-serializable typesval parcelable: SomeParcelable// Android Parcelable is not Java Serializable by default) : Screen {// ...}
Not only the params, but the properties will also be restored, so the same rule applies.
// ✔️ DO@ParcelizedataclassPost(/*...*/) : Parcelable@ParcelizedataclassValidScreen(val post: Post// Your own parcelable types) : Screen, Parcelable {// ...}// 🚫 DON'TclassPost(/*...*/)@ParcelizedataclassInvalidScreen(val context: Context, // Built-in non-parcelable typesval post: Post, // Your own non-parcelable typesval serializable: SomeSerializable// Java Serializable are not Android Parcelable by default) : Screen, Parcelable {// ...}
Enforcing Android Parcelable on your screens
You can build your own Screen type for enforcing in at compile time that all yours screens should be Parcelable by creating an interface that implement Parcelable.
When working in a Multiplatform project and sharing the Parameters models with other platforms, your types required to be serializable in a Bundle if you are targeting Android, the easiest way is defining in common code a JavaSerializable interface that on Android only would implement java.io.Serialiable, see example below.
If you want to inject dependencies through a DI framework, make sure it supports Compose, like Koin and Kodein.
// ✔️ DOclassValidScreen : Screen {@ComposableoverridefunContent() {// Inject your dependencies inside composablesval postService =get<PostService>() }}// 🚫 DON'TclassInvalidScreen : Screen {// Using DI to inject non-serializable types as propertiesval postService byinject<PostService>()}
Identifying screens
The Screen interface has a key property used for saving and restoring the states for the subtree. You can override the default value to set your own key.