According to release notes here SavedState now supprots kotlix.serialization. So I'm trying to lavarage it for navigation. It works as expected for nav args but when I'm trying to pas it as a result to the previous BackStackEntry it either crashes or does nothing.
If I call
navController.previousBackStackEntry?.savedStateHandle?.set("RESULT", brand)
It crashes with
java.lang.IllegalArgumentException: Can't put value with type class com.....brands.data.dto.BrandDto into saved state
at androidx.lifecycle.SavedStateHandle.set(SavedStateHandle.android.kt:151)
If I'm using
private var result by resultHandle.saved(RESULT_BRAND_EDIT) { brand }
...
result = brand
navController.popBackStack()
and
private val brand by savedStateHandle.saved(RESULT_BRAND_EDIT) { BrandDto(name = "") }
...
product.brand = brand
When I read this value (when the screen onResume is triggered after navigation back), it returns the default value for brand, not the one I put in the code above.
So I'm wondering if is a problem with the framework or am I doing something wrong? Is there any example of working code for such scenario?
When you use by savedStateHandle.saved
, you aren't storing the value itself inside the SavedStateHandle
(@Serializable
classes by themselves aren't saveable), but instead you are using the SavedState 1.3 Serialization Support:
KotlinX Serialization Support
- SavedState now includes KotlinX Serialization support. You can convert a class annotated with
@Serializable
to aSavedState
using the methodsencodeToSavedState
anddecodeFromSavedState
. The returnedSavedState
is a regularBundle
on Android and can be used by any API that accepts aBundle
.
The by savedStateHandle.saved
is doing that encodeToSavedState
and decodeToSavedState
for you.
When you manually call set
, you aren't using the property delegate, so you need to manually call encodeToSavedState
:
navController.previousBackStackEntry?.savedStateHandle?.set(
"RESULT",
encodeToSavedState(brand) // Manually encode it as something SavedStateHandle can...handle
)