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

Kotlin多平台开启ProGuard后序列化报错:找不到类序列化器

问题:开启代码混淆后Kotlinx序列化报错

现象

构建应用时,设置isMinifyEnabled = false可正常运行;启用该选项后,出现序列化相关报错。

报错堆栈

ea.j: Serializer for class 'b' is not found.
                                                                                                    
Mark the class as @Serializable or provide the serializer explicitly.
                                                                                                         
at ia.d1.d(Unknown Source:33)
                                                                                                         
at ia.c1.l(Unknown Source:5)
                                                                                                         
at ea.m.d(Unknown Source:22)
                                                                                                         
at ea.l.b(Unknown Source:0)
                                                                                                         
at ua.a$b.l(Unknown Source:79)
                                                                                                         
at ua.a$b.o(Unknown Source:8)
                                                                                                         
at ua.a$b.Z(Unknown Source:4)
                                                                                                         
at e8.a.b(Unknown Source:249)
                                                                                                         
at e8.a$a.l(Unknown Source:10)
...

序列化类定义

@Serializable
data class LoginResponse(val accessTokens: ServerTokens, val magisterTokens: TokenResponse, val tenantUrl: String, @Required val type: Int = 1) // Types: 1 = completion

相关业务代码

client.webSocket(host = SERVER_URL, port = 8080, path = EXCHANGE_URL.encodedPath) {
    send(Json.encodeToString(loginRequest))
    incoming.consumeEach { frame ->
        println("Received frame: $frame")
        if (frame is Frame.Text) {
            val json = Json.parseToJsonElement(frame.readText()).jsonObject
            if (json["type"].toString().toInt() == 1) {
                response = Json.decodeFromString<LoginResponse>(frame.readText()) // <--- 推测此处为问题代码
            }
        } else if (frame is Frame.Close) {
            if (frame.readReason()?.knownReason != CloseReason.Codes.NORMAL) {
                println("Error: ${frame.readReason()?.message}")
                throw Exception("Received: ${frame.readReason()?.message}")
            }
        }
    }
}

已尝试无效方案

  • 应用Kotlinx序列化官方Android混淆规则
  • 清理并重建项目
  • 添加自定义混淆规则

项目环境

  • Kotlin 1.7.10
  • Kotlin Multiplatform
  • KotlinX Serialization Json 1.4.0
  • Ktor 2.0.3
  • 注:@Serializable类位于多平台项目的shared模块,序列化操作在androidApp模块中执行

解决方案

1. 配置shared模块的混淆规则

KMM项目中,shared模块需单独配置混淆规则,不能仅在androidApp模块设置:

  1. 在shared模块的build.gradle.kts中启用混淆:
android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}
  1. 在shared模块的proguard-rules.pro中添加序列化保护规则:
# Kotlinx Serialization 基础保护规则
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.SerializationKt
-keep,includedescriptorclasses class **$$serializer { *; }
-keepclassmembers class ** {
    *** Companion;
}
-keepclasseswithmembers class ** {
    kotlinx.serialization.KSerializer serializer(...);
}

# 保留项目中所有序列化类及嵌套类
-keep @kotlinx.serialization.Serializable class ** { *; }
-keep class com.yourpackage.LoginResponse, com.yourpackage.ServerTokens, com.yourpackage.TokenResponse { *; }

替换com.yourpackage为项目实际包名。

2. 显式指定序列化器

在反序列化时直接传入类的序列化器,避免混淆后反射找不到类:

// 替换原有反序列化代码
response = Json.decodeFromString(LoginResponse.serializer(), frame.readText())

3. 升级依赖版本

Kotlin 1.7.10推荐搭配Kotlinx Serialization 1.4.1,当前1.4.0可能存在兼容性问题,升级依赖:
在shared模块的build.gradle.kts中修改:

plugins {
    kotlin("multiplatform")
    kotlin("plugin.serialization") version "1.7.10"
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
}

4. 临时禁用R8全模式

若以上方法均无效,可临时关闭R8全模式(不建议长期使用),在项目根目录的gradle.properties中添加:

android.enableR8.fullMode=false

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:55:16