State restoration¶
Every instance of Screen
is expected to be savable in
a Bundle, therefore all params and
properties of your Screen
implementations should be either Java Serializable
or Parcelable
. Otherwise, your app
will crash upon attempting to restore its state.
Keep in mind that Parcelables
are not Java Serializable
by default and Java Serializables
are not Parcelable
by
default.
Java Serializable¶
// ✔️ DO
data class Post(/*...*/) : java.io.Serializable
data class ValidScreen(
val userId: Long, // Built-in serializable types
val post: Post // Your own serializable types
) : Screen {
// Serializable properties
val tag = "ValidScreen"
// Lazily initialized serializable types
val randomId by lazy { UUID.randomUUID() }
// ...
}
// 🚫 DON'T
class Post(/*...*/)
data class InvalidScreen(
val context: Context, // Built-in non-serializable types
val post: Post, // Your own non-serializable types
val parcelable: SomeParcelable // Android Parcelable is not Java Serializable by default
) : Screen {
// Non-serializable properties
val postService = PostService()
// ...
}
Android Parcelables¶
// ✔️ DO
@Parcelize
data class Post(/*...*/) : Parcelable
@Parcelize
data class ValidScreen(
val post: Post // Your own parcelable types
) : Screen, Parcelable {
// ...
}
// 🚫 DON'T
class Post(/*...*/)
@Parcelize
data class InvalidScreen(
val context: Context, // Built-in non-parcelable types
val post: Post, // Your own non-parcelable types
val 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.
interface ParcelableScreen : Screen, Parcelable
// Compile
@Parcelize
data class Post(/*...*/) : Parcelable
@Parcelize
data class ValidScreen(
val post: Post
) : ParcelableScreen {
// ...
}
// Not compile
data class Post(/*...*/)
@Parcelize
data class ValidScreen(
val post: Post
) : ParcelableScreen {
// ...
}
Multiplatform state restoration¶
When working in a Multiplatform project you may need a common Java Serializable
or Parcelable
interface/annotation,
you can create one like this:
// commonMain - module core
expect interface JavaSerializable
// androidMain - module core
actual typealias JavaSerializable = java.io.Serializable
// non AndroidMain (ios, web, etc) - module core
actual interface JavaSerializable
Identifying screens¶
The Screen
interface has a key
property that defines it in each Navigator
.
The default key for a Screen
is its name. You can override it to set your own key.
data class HomeScreen(
override val key: String = "CUSTOM_KEY"
) : Screen {
@Composable
override fun Content() {
// ...
}
}
Vortex also has a uniqueScreenKey
function, that generates a random key.
override val key = uniqueScreenKey()