使用Jetpack Compose导航组件时遭遇Kotlin序列化MissingFieldException与SerializationException问题求助
Hey there, let's break down these two serialization headaches you're facing with Jetpack Compose Navigation and Kotlinx Serialization, and fix them step by step!
Problem 1: MissingFieldException when removing default values from User data class
What's causing this?
When you strip out the default values from your User data class, Kotlinx Serialization expects every non-nullable field to be present in the serialized JSON. But your custom UserType NavConfig has encodeDefaults = false, which means fields set to their default values don't get included in the serialized output. So if you pass a User object where some fields use the old defaults (like an empty string for email), those fields won't show up in the JSON—and when deserializing, the serializer throws a fit because it can't find required fields.
Fixes you can try:
Keep default values in User (simplest fix)
If your use case allows it, leave the default values in theUserdata class. This way, even if a field is missing from the serialized JSON, Kotlinx Serialization will fill it in with the default value instead of throwing an error.Adjust your Json config to include defaults
ChangeencodeDefaultstotruein yourUserTypesetup. This ensures every field (even those with default values) gets serialized, so deserialization will never miss required fields:val UserType = object : NavType<User>(isNullableAllowed = false) { private val json = Json { ignoreUnknownKeys = true isLenient = true encodeDefaults = true // Flip this to true explicitNulls = false prettyPrint = true } // Rest of your methods stay the same }Ensure all User fields are populated before navigation
If you really don't want default values, make sure every non-nullable field inUserhas a valid value when you pass it to theHomedestination. This way, all required fields will be present in the serialized JSON.
Problem 2: SerializationException about missing Companion serializer when removing default User from Home destination
What's causing this?
When you remove the default User value from the Home data class, the Jetpack Navigation component's serialization logic can get confused. It might accidentally try to serialize the Companion object associated with the Home class (which isn't marked @Serializable), leading to that error. Alternatively, your custom UserType might not play nicely with a destination that requires a mandatory parameter with no default.
Fixes you can try:
Always pass a User explicitly when navigating to Home
Make sure whenever you callnavigateto go to theHomescreen, you provide a validUserobject—no exceptions. For example:navController.navigate(Destination.Home(user = currentLoggedInUser))Ditch the custom NavType and use built-in serialization
Jetpack Navigation now has native support for Kotlinx Serialization, which can avoid these custom type issues entirely. Update your composable registration to let Navigation handle serialization automatically:// No need for typeMap anymore composable<Destination.Home> { backStackEntry -> val viewModel = koinViewModel<HomeViewModel>() val homeData = backStackEntry.toRoute<Destination.Home>() eVoteViewModel.setUser(homeData.user) val state by viewModel.state.collectAsStateWithLifecycle() HomeScreen( state = state, user = homeData.user, copyToClipboard = viewModel::copyToClipboard ) }Double-check your sealed interface serialization
Ensure yourDestinationsealed interface and all its subclasses are properly marked@Serializable. Sometimes, subtle issues with sealed type serialization can lead to strange Companion-related errors.
备注:内容来源于stack exchange,提问作者OmniCoder77

