Retrofit-Kotlin非空对象类型空指针异常问题求助
解决Retrofit+Kotlin传递Parcelable时因null字段崩溃的问题
嘿,刚上手Android架构组件和Retrofit的时候踩过一模一样的坑,太懂这种莫名其妙崩溃的憋屈感了!咱们来一步步拆解问题:
问题根源
你说调用API时description为null应用没崩溃,但传递Parcelable时崩了——核心原因就是Parcelable序列化/反序列化过程中没有正确处理nullable字段。Retrofit解析null到可空字段时没问题,但Intent传递Parcelable需要完整的序列化流程,这里如果处理不当就会触发异常。
解决方案分两种情况:
1. 用Kotlin的@Parcelize注解实现Parcelable(推荐)
这是Kotlin官方提供的简化Parcelable实现的方式,只要配置正确,它会自动处理可空类型:
- 首先确保你的模块
build.gradle里引入了parcelize插件:plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-parcelize' // 必须添加这个插件 } - 然后你的数据类要明确标记可空字段:
这种方式下,import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize data class GithubRepo( val id: Int, val name: String, val description: String?, // 这里必须标记为可空类型 // 其他从GitHub API返回的字段... ) : Parcelable@Parcelize会自动生成支持null的序列化代码,完全不用你手动处理细节。
2. 手动实现Parcelable(不推荐,但如果必须用的话)
如果是自己写Parcelable的createFromParcel和writeToParcel方法,一定要注意对null的处理:
import android.os.Parcel import android.os.Parcelable data class GithubRepo( val id: Int, val name: String, val description: String? ) : Parcelable { override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeInt(id) parcel.writeString(name) parcel.writeString(description) // writeString天然支持写入null } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<GithubRepo> { override fun createFromParcel(parcel: Parcel): GithubRepo { return GithubRepo( parcel.readInt(), parcel.readString()!!, // name是GitHub API必填字段,用!!没问题 parcel.readString() // readString会返回null,刚好匹配可空字段 ) } override fun newArray(size: Int): Array<GithubRepo?> { return arrayOfNulls(size) } } }
这里关键是用writeString和readString,它们对null的支持是原生的,别用其他可能不处理null的自定义序列化逻辑。
额外排查点
- 先看崩溃的具体栈日志:如果是
NullPointerException,大概率是你在反序列化时不小心给可空字段加了!!强制非空;如果是Parcel相关的IO异常,那就是序列化逻辑有问题。 - 确认Retrofit的解析器(比如Gson/Moshi)配置正确:Gson默认支持Kotlin的可空类型,不用额外配置,但如果你自定义了解析规则,要确保没把null转成空字符串或者其他奇怪的东西。
内容的提问来源于stack exchange,提问作者Tarun Chauhan
相关产品推荐
相关产品推荐

