You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose类型安全导航传递可空Task数据类时无参数导航崩溃问题

Jetpack Compose类型安全导航传递可空Task数据类时无参数导航崩溃问题

我来帮你分析并解决这个问题,你遇到的崩溃是因为自定义NavType对null值的处理逻辑和类型安全导航框架的交互出现了冲突,导致框架错误地尝试序列化Task类的默认Companion对象(这个对象没有标记@Serializable,所以抛出了序列化异常)。

问题原因拆解

当你调用navController.navigate(TaskRoutes.AddTaskScreen)时,路由的task参数使用默认值null,但你的自定义NavType中把null值序列化为字符串"null"存入Bundle,在框架解析时,这个处理逻辑和类型安全导航的序列化流程产生了冲突,意外触发了对Task.Companion的序列化尝试。

解决方案

你可以通过调整自定义NavType的null值处理逻辑来解决这个问题,同时确保路由类的定义正确:

1. 修正CustomNavType的null值处理逻辑

把原来存入字符串"null"的逻辑改为直接存入null,或者当值为null时不向Bundle中添加该参数,这样框架就能正确识别null值,不会触发错误的序列化行为:

object CustomNavType {

    val TaskType = object : NavType<Task?>(isNullableAllowed = true) {
        private val taskSerializer = Task.serializer()

        override fun get(bundle: Bundle, key: String): Task? {
            // 当Bundle中没有对应key时,直接返回null
            return bundle.getString(key)?.let { Json.decodeFromString(taskSerializer, it) }
        }

        override fun parseValue(value: String): Task? {
            // 处理空字符串和"null"字符串,都返回null
            return if (value.isBlank() || value == "null") {
                null
            } else {
                Json.decodeFromString(taskSerializer, Uri.decode(value))
            }
        }

        override fun put(bundle: Bundle, key: String, value: Task?) {
            // 仅当value不为null时才存入Bundle,null时不添加该参数
            value?.let {
                bundle.putString(key, Json.encodeToString(taskSerializer, it))
            }
        }

        override fun serializeAsValue(value: Task?): String {
            // null时返回空字符串,避免框架解析异常
            return value?.let { Uri.encode(Json.encodeToString(taskSerializer, it)) } ?: ""
        }
    }
}

2. 确保路由类的参数默认值正确配置

你的TaskRoutes.AddTaskScreen必须是带可空默认值的@Serializable数据类,这样无参数调用时才能正确生成task为null的路由实例:

@Serializable
sealed class TaskRoutes {
    @Serializable
    data class AddTaskScreen(val task: Task? = null) : TaskRoutes()
}

3. 验证修改效果

现在调用navController.navigate(TaskRoutes.AddTaskScreen)时,task参数会被正确解析为null,不会再触发序列化异常;调用navController.navigate(TaskRoutes.AddTaskScreen(task))时也能正常传递Task对象。

备注:内容来源于stack exchange,提问作者Ahmad Nasser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 08:47:59