Kotlin @Parcelize序列化时writeToParcel()抛空指针异常求助
解决@Parcelize传递嵌套数据类时的NullPointerException问题
这个问题我之前也碰到过,根源是@Parcelize在处理非空但实际为null的List字段时没有做空值保护:当你的某个List类型字段被赋值为null时,生成的Parcelable序列化代码会直接调用size()方法,触发空指针异常。从你的异常栈可以看到,崩溃恰好发生在Features.writeToParcel中调用Collection.size(),说明Features类里的Fields List字段是null。
下面是具体的解决思路和步骤:
1. 给所有List类型字段添加非空默认值
在Kotlin数据类中,为所有List字段设置emptyList()作为默认值,这样即使数据来源返回null,或者你创建对象时未赋值,都会自动用空集合代替null,避免空指针。修改后的代码如下:
@Parcelize data class Response(val RecordView: RecordView = RecordView()) : Parcelable @Parcelize data class RecordView(val Records: List<Records> = emptyList()) : Parcelable @Parcelize data class Gid(val Value: String = "") : Parcelable @Parcelize data class Features( val Fields: List<Fields> = emptyList(), val FeatureName: String = "", val Title: String = "" ) : Parcelable @Parcelize data class Fields( val Label: String = "", val Value: String = "", val FieldName: String = "", val Features: List<Features> = emptyList() ) : Parcelable @Parcelize data class Records( val Gid: Gid = Gid(), val ImageIds: List<String> = emptyList(), val Fields: List<Fields> = emptyList(), val Features: List<Features> = emptyList() ) : Parcelable
2. 检查数据解析逻辑(如果是接口数据)
如果你的数据来自接口解析(比如用Gson/Moshi),要确保解析器不会把JSON中的null数组赋值给List字段。虽然上面的默认值已经能兜底,但如果想从源头避免,可以配置解析器将null数组转换为空集合:
- 对于Gson:可以自定义TypeAdapter,或者结合数据类默认值使用
GsonBuilder().serializeNulls(); - 对于Moshi:使用
@Json(defaultValue = "[]")注解(需要配合相应的适配器)。
3. 确认Intent传递的类型匹配
虽然你的异常是序列化阶段的问题,但也要确保传递和接收的类型完全一致:
// 发送方示例:传递Records对象 val targetRecord = response.RecordView.Records.firstOrNull() targetRecord?.let { val intent = Intent(this, NextActivity::class.java) intent.putExtra(RECORD, it) startActivity(intent) } // 接收方示例:正确接收Records类型 val record = intent?.getParcelableExtra<Records>(RECORD)
补充说明
@Parcelize生成的Parcelable代码会严格遵循Kotlin的非空声明,如果你标记某个字段为非空(比如val Fields: List<Fields>),它会假设该字段永远不会为null,不会自动添加空值判断。因此给集合字段设置默认空集合是最符合Kotlin非空安全理念的解决方案,同时也能避免序列化时的空指针问题。
内容的提问来源于stack exchange,提问作者TooManyEduardos
相关产品推荐
相关产品推荐

