Kotlin中Moshi Enum适配器未被调用问题求助
解决Moshi自定义枚举适配器未被调用的问题
我之前也踩过类似的坑,你的问题核心有两个:Moshi 1.6.0版本对嵌套在枚举内部的适配器类支持有限,加上旧版本的适配器注册逻辑存在限制。下面一步步帮你解决:
问题根源
从错误堆栈能明显看到,Moshi一直在用默认的EnumJsonAdapter处理你的Status枚举,完全没用到你写的自定义适配器。这是因为在Moshi 1.6.0的AdapterMethodsFactory逻辑中,不会识别嵌套在枚举类内部的适配器类——它只会扫描顶层类或带有特定注解的类,嵌套枚举里的类不在扫描范围内。
解决方案
方案1:升级Moshi版本(推荐)
Moshi后续版本(比如1.10.0+)修复了嵌套类适配器的识别问题,同时新增了更多Kotlin友好的特性。先把依赖升级到稳定版:
implementation 'com.squareup.moshi:moshi:1.15.0' implementation 'com.squareup.moshi:moshi-kotlin:1.15.0'
升级后,你可以保留原来的嵌套适配器写法,或者用更简洁的方式:给枚举的companion object添加@JsonAdapter注解,让Moshi自动识别适配器:
enum class Status { IDLE, IN_PROGRESS, FAILED, SUCCESS, UNKNOWN; companion object { private val map = Status.values().associateBy(Status::ordinal); fun fromInt(type: Int?): Status = map[type] ?: UNKNOWN @JsonAdapter class Adapter { @ToJson fun toJson(status: Status): Int = status.ordinal @FromJson fun fromJson(value: Int): Status = fromInt(value) } } }
这样甚至不需要手动在Moshi.Builder里添加适配器,Moshi会自动扫描并使用它。
方案2:不升级版本,调整适配器位置
如果暂时不能升级依赖,把适配器类从枚举内部移出来,作为顶层类或非嵌套类:
enum class Status { IDLE, IN_PROGRESS, FAILED, SUCCESS, UNKNOWN; companion object { private val map = Status.values().associateBy(Status::ordinal); fun fromInt(type: Int?): Status = map[type] ?: UNKNOWN } } // 顶层适配器类 class StatusAdapter { @ToJson fun toJson(status: Status): Int = status.ordinal @FromJson fun fromJson(value: Int): Status = Status.fromInt(value) }
然后在构建Moshi时,保持自定义适配器放在KotlinJsonAdapterFactory之前(你原来的顺序是正确的,继续保留即可):
@Provides @Singleton fun provideMoshi(): Moshi { return Moshi.Builder() .add(StatusAdapter()) .add(KotlinJsonAdapterFactory()) .build() }
额外验证
你可以在构建Moshi后,打印对应Status类的适配器,确认是否使用了自定义的:
val moshi = provideMoshi() val adapter = moshi.adapter(Status::class.java) println(adapter.javaClass.name) // 应该输出你的适配器类名,而非StandardJsonAdapters$EnumJsonAdapter
这样就能确保自定义适配器被正确加载,不会再抛出默认适配器的错误了。
内容的提问来源于stack exchange,提问作者Sky Kelsey
相关产品推荐
相关产品推荐

