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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:10:02