You need to enable JavaScript to run this app. Android调试版REST调用传参正常 签名APK中POST请求pass字段为null
优惠活动
大模型
产品
解决方案
定价
更多

Android调试版REST调用传参正常 签名APK中POST请求pass字段为null

问题根本原因

这个现象和POST请求本身的业务逻辑完全无关,是Android Release签名构建默认开启的R8/ProGuard代码压缩混淆机制导致的。

  • 调试构建默认关闭代码压缩,所有类、字段、方法都保留原始定义,Retrofit通过反射序列化User对象时,能正确读取到name和pass字段,生成符合服务端要求的JSON请求体。
  • Release签名构建默认开启代码压缩,R8会通过静态字节码扫描判定无用代码,对没有被“直接代码调用”的类、方法、字段执行移除或重命名操作。R8无法识别反射调用逻辑(Retrofit的序列化过程完全基于反射实现)。
  • 为什么只有pass字段丢失?对照你定义的User类逻辑就能发现:
    • name字段在多个构造函数、本地用户信息读取、登录态展示等业务逻辑里被直接读写,R8判定它为有效代码,不会修改它的字段名。
    • pass字段仅在双参/三参构造函数里被赋值,你的客户端业务代码全程没有直接调用getPass()或读取pass字段的逻辑,R8判定这个字段、对应的getter/setter都是无用代码,直接从类结构中移除或重命名。最终序列化生成的JSON里根本没有pass键,服务端接收到的自然就是null。
修复方案

在app模块的proguard-rules.pro混淆规则文件中添加白名单,阻止R8修改需要被网络序列化的实体类:

  1. 针对当前的User类,直接添加规则:
    -keep class com.你的应用包名.User { *; }
    这条规则会让R8保留这个类的所有结构、方法、字段,不做任何修改。
  2. 如果使用Gson作为Retrofit的JSON转换器,可以补充通用的Gson混淆规则,避免后续新增实体类再出现同类问题:
    # 保留Gson核心类
    -keep class com.google.gson.** { *; }
    # 保留类上的注解信息,支持@SerializedName等注解
    -keepattributes *Annotation*
    # 保留所有实体类的字段定义
    -keep class com.你的应用包名.model.** { <fields>; }
    

修改完成后重新生成Release签名包,序列化行为就会和调试版本完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 13:24:05