Status Update
Comments
jb...@google.com <jb...@google.com>
cl...@google.com <cl...@google.com>
ap...@google.com <ap...@google.com> #2
Branch: androidx-main
commit f350f4295432b8d3d99b589501b73b5caa58184d
Author: Clara Fok <clarafok@google.com>
Date: Wed Jul 24 16:10:16 2024
Add built-in support for NavType.EnumType
Navigation in safe args now has built-in support for argument of NavType.EnumType. This means Enum types no longer require custom NavTypes.
Note:
The serialziable Enum class must use the default SerialName. Do not override name with @SerialName.
Test: ./gradlew navigation:navigation-common:test
Test: ./gradlew navigation:navigation-common:cC
Test: ./gradlew navigation:navigation-runtime:cC
Bug: 346475493
Relnote: "Navigation in safe args now has built-in support for argument of NavType.EnumType. This means Enum types no longer require custom NavTypes. Note that the Enum’s SerialName must be the default fully qualified name."
Change-Id: I66d22e2004a9c996688f082f1732b7f4c4e8ca24
M navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/RouteFilledTest.kt
M navigation/navigation-common/src/androidTest/java/androidx/navigation/serialization/TestUtil.kt
M navigation/navigation-common/src/main/java/androidx/navigation/serialization/NavTypeConverter.kt
M navigation/navigation-common/src/test/java/androidx/navigation/serialization/NavArgumentGeneratorTest.kt
M navigation/navigation-common/src/test/java/androidx/navigation/serialization/NavTypeConverterTest.kt
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerRouteTest.kt
cl...@google.com <cl...@google.com> #3
je...@gmail.com <je...@gmail.com> #4
This still seems to be broken with 2.8.0-beta07
Here is the simple setup
package org.jdc.template.ux.test
enum class TestEnum {
ONE,
TWO
}
@Serializable
data class TestRoute(
val testEnum: TestEnum
)
package org.jdc.template.ux
@Composable
fun NavGraph(
navController: NavHostController,
) {
NavHost(navController = navController, startDestination = StartRoute) {
composable<TestRoute> { } // CRASH happens HERE
}
}
The exception I'm seeing is:
java.lang.IllegalArgumentException: Cannot find class with name "org.jdc.template.ux.test.TestEnum". Ensure that the serialName for this argument is the default fully qualified name
at androidx.navigation.serialization.NavTypeConverterKt.getClass(NavTypeConverter.kt:146)
at androidx.navigation.serialization.NavTypeConverterKt.getNavType(NavTypeConverter.kt:92)
at androidx.navigation.serialization.RouteSerializerKt.computeNavType(RouteSerializer.kt:159)
at androidx.navigation.serialization.RouteSerializerKt.forEachIndexedKType(RouteSerializer.kt:185)
at androidx.navigation.serialization.RouteSerializerKt.generateRoutePattern(RouteSerializer.kt:62)
at androidx.navigation.serialization.RouteSerializerKt.generateRoutePattern$default(RouteSerializer.kt:45)
at androidx.navigation.NavDestinationBuilder.<init>(NavDestinationBuilder.kt:92)
at androidx.navigation.compose.ComposeNavigatorDestinationBuilder.<init>(ComposeNavigatorDestinationBuilder.kt:95)
at org.jdc.template.ux.NavGraphKt.NavGraph$lambda$2(NavGraph.kt:246)
Debugging at where it is crashing, I'm seeing that className IS equal to "org.jdc.template.ux.test.TestEnum" in SerialDescriptor.getClass().... but failing to find the class (it is always throwing ClassNotFoundException)
To double-check things (test if I also get a ClassNotFoundException), I put the following code in above the NavHost:
Class.forName("org.jdc.template.ux.test.TestEnum")
I get NO exception in my code (I don't know why SerialDescriptor.getClass() cannot find the class)
lu...@gmail.com <lu...@gmail.com> #6
I got the same issue as
Even if regular enums are implicitly Serializable
, you still need to add it or the issue Ensure that the serialName for this argument is the default fully qualified name
will appear.
package org.jdc.template.ux.test
@Serializable
enum class TestEnum {
ONE,
TWO
}
@Serializable
data class TestRoute(
val testEnum: TestEnum
)
You will also need to specified type in the declaration of your route:
composable<Route.TestRoute>(
typeMap = mapOf(
typeOf<TestEnum>() to NavType.EnumType(TestEnum::class.java)
),
) {
...
}
During my investigations, I've found that if you declare it like this:
package org.jdc.template.ux.test
@Serializable
data class TestRoute(
val testEnum: TestEnum
) {
enum class TestEnum {
ONE,
TWO
}
}
It will work on non-minified code, but it won't after minifying and you will get same error as before.
pr...@google.com <pr...@google.com> #8
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.navigation:navigation-common:2.8.0-beta07
androidx.navigation:navigation-runtime:2.8.0-beta07
Description
Component used: Navigation: androidx.navigation:navigation-compose
Version used: 2.8.0-beta02
Per Ian's comment here https://issuetracker.google.com/issues/346505952#comment2 it should not be needed.
Repro here:https://github.com/hrach/navigation-compose/commit/6342c95cc0c57a5e8598f92241d59a658c538071