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

启用R8的Release构建中Typesafe Navigation序列化INSTANCE缺失问题

问题分析与解决方案

根本原因

R8在Release构建的代码收缩优化过程中,会移除它判定为无直接引用的类成员。对于嵌套的@Serializable data object(如OwnerGraph.HistoryGraph):

  • 它作为导航图的泛型参数被使用,而Java/Kotlin的泛型会在编译时发生类型擦除,R8的静态分析无法识别到它被kotlinx.serialization的反射机制间接引用;
  • 最终R8会删除该object的INSTANCE静态字段,同时移除kotlinx.serialization插件为其生成的序列化器元数据,导致运行时找不到对应序列化器,抛出异常。

解决方案

1. 显式引用序列化器(推荐)

在导航图配置代码中,显式调用目标类的serializer()方法,让R8明确感知到该类被使用:

fun NavGraphBuilder.historyScreenOwnerNavGraph() {
    // 显式引用序列化器,阻止R8优化移除
    val _ = OwnerGraph.HistoryGraph.serializer()
    val _ = OwnerGraph.HistoryGraph.HistoryScreen.serializer()
    
    navigation<OwnerGraph.HistoryGraph>(
        startDestination = OwnerGraph.HistoryGraph.HistoryScreen
    ) {
        composable<OwnerGraph.HistoryGraph.HistoryScreen> { navBackStackEntry ->
            val navHostController = LocalNavHostController.current
            Text("History Screen")
        }
    }
}

2. 添加@Keep注解(快速修复)

直接给被优化移除的data object添加@Keep注解,强制R8保留该类的所有成员和元数据:

@Serializable
data object OwnerGraph {
    
    @Keep
    @Serializable
    data object HistoryGraph {
        
        @Serializable
        data object HistoryScreen
    }
}

3. 配置全局R8规则(批量处理)

如果项目中有多个类似的嵌套序列化object,可在proguard-rules.pro中添加全局规则,自动保留所有@Serializable标识的object类及其序列化相关内容:

# 保留@Serializable注解的类名
-keepnames class @kotlinx.serialization.Serializable *

# 保留所有序列化器的INSTANCE字段
-keepclassmembers class ** implements kotlinx.serialization.KSerializer {
    public static ** INSTANCE;
}

# 保留@Serializable标识的object类的INSTANCE字段
-keepclassmembers @kotlinx.serialization.Serializable class ** {
    public static final ** INSTANCE;
}

内容的提问来源于stack exchange,提问作者No_Name

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:47:07