Flutter发布版中Kotlin参数名变字母标识致功能异常求助
问题描述
将Flutter应用构建为发布版并部署到Play Console内部测试轨道时,部分Flutter功能失效。通过EventChannels将Kotlin原生函数的数据流式传输到Flutter端用于构建对象,debug模式下Kotlin生成的JSON字符串参数名键正常,但发布版中键变为a:、b:、c:等字母标识。未启用混淆配置,无法在Flutter类的toJson()方法中同时适配真实参数名和字母标识,需解决发布版中恢复正常参数名键值的问题。
相关Kotlin类代码:
class ScanResponseModel(var name: String, var mac: String, var axis: String, var number : String)
Debug模式下JSON输出:
[{ "name":"2325", "mac":"D4:1C:32:33:EE:1F", "axis":"left", "number":"0002325" }, { "name":"2122", "mac":"DC:20:3F:E7:05:B7", "axis":"right", "number":"0002122" }]
Release模式下JSON输出:
[{ "a":"2325", "b":"D4:1C:32:33:EE:1F", "c":"left", "d":"0002325" }, { "a":"2122", "b":"DC:20:3F:E7:05:B7", "c":"right", "d":"0002122" }]
解决方案
该问题源于R8代码优化——即使未开启混淆,release模式下R8默认会对未标记的类做字段名精简优化,将原字段名替换为短字母,进而影响JSON序列化的键名。以下是几种可行解决方法:
方法1:给Kotlin类添加序列化注解(推荐)
根据你使用的序列化工具,给字段添加注解明确指定序列化键名:
- 若使用Gson:
import com.google.gson.annotations.SerializedName class ScanResponseModel( @SerializedName("name") var name: String, @SerializedName("mac") var mac: String, @SerializedName("axis") var axis: String, @SerializedName("number") var number : String )
- 若使用Kotlinx Serialization:
import kotlinx.serialization.Serializable import kotlinx.serialization.SerialName @Serializable class ScanResponseModel( @SerialName("name") var name: String, @SerialName("mac") var mac: String, @SerialName("axis") var axis: String, @SerialName("number") var number : String )
注解会强制序列化工具使用指定键名,不受R8优化影响。
方法2:配置R8规则保留类字段名
在android/app/proguard-rules.pro文件中添加规则,保留目标类的字段名:
-keepclassmembers class com.yourpackage.ScanResponseModel { <fields>; }
将com.yourpackage替换为该类实际的包名,R8优化时将不会修改此类的字段名。
方法3:关闭R8的字段精简优化(不推荐)
在android/app/build.gradle的buildTypes中给release版本添加配置,关闭字段名优化:
android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 添加该行关闭R8全模式优化 android.enableR8.fullMode = false } } }
此方法会影响整体代码优化效果,不建议全局使用,优先选择前两种方案。
内容的提问来源于stack exchange,提问作者JadedEric
相关产品推荐
相关产品推荐

