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

Kotlin Data Class出现异常结果:含@Parcelize的MemberCard类问题咨询

Troubleshooting & Fixes for Your @Parcelize MemberCard Data Class

Hey there, let's dig into why your @Parcelize-annotated MemberCard data class is throwing exceptions. I’ve run into most of these issues myself, so here’s a step-by-step breakdown of what to check and fix:

1. Double-Check Parcelize Plugin & Dependencies

If you haven’t configured the Kotlin Parcelize plugin properly, that’s almost certainly the first issue to resolve:

  • In your app-level build.gradle (or build.gradle.kts), confirm the plugin is applied:
    // Groovy syntax
    plugins {
        id 'kotlin-parcelize'
    }
    
    // Kotlin DSL syntax
    plugins {
        id("kotlin-parcelize")
    }
    
  • Also, make sure your Kotlin version is up-to-date—older versions have known bugs with complex data classes using @Parcelize.

2. Validate Your Parent Interface Setup

Your MemberCard uses override on fields like MembershipNumber and ExpirationDate, which means it’s inheriting from a parent interface (let’s say something like BaseMembership). For @Parcelize to work smoothly:

  • The parent interface must extend Parcelable
  • All overridden properties need to be included in parcelization. If the parent has abstract properties, @Parcelize should handle them automatically, but double-check none of these fields are marked transient (that would exclude them from serialization entirely).

3. Fix the Date Type (It’s Not Parcelable by Default!)

The ExpirationDate field uses Date, which isn’t a default supported type for @Parcelize. Kotlin’s Parcelize only handles basic types, collections of supported types, and other Parcelable classes out of the box. You’ve got two solid fixes here:

Option 1: Use a Timestamp (Simplest Approach)

Replace Date with a Long (store the timestamp) and convert back to Date when you need it:

@Parcelize
data class MemberCard(
    val PartnerMembershipId: Int,
    override var MembershipNumber: String? = null,
    override var Name: String? = null,
    var MemberImgUrl: String? = null,
    val TextColorHex: String? = null,
    override var ExpirationDate: Long? = null, // Store timestamp instead of Date
    override var Issuer: String,
    var Notifications: kotlin.Int? = null,
    override var BarcodeType: kotlin.String? = null,
    override var Barcode: kotlin.String? = null,
    val IsPartnerCard: Boolean,
    val Status : String
) : BaseMembership { // Replace with your actual parent interface
    // Helper method to convert back to Date
    fun getExpirationDateAsDate(): Date? = ExpirationDate?.let { Date(it) }
}

Option 2: Create a Custom Parceler for Date

If you want to keep using Date, make a custom parceler to handle serialization:

// Define the parceler
object DateParceler : Parceler<Date> {
    override fun create(parcel: Parcel): Date = Date(parcel.readLong())
    override fun Date.write(parcel: Parcel, flags: Int) = parcel.writeLong(time)
}

// Apply it to your data class
@Parcelize
@TypeParceler<Date, DateParceler>()
data class MemberCard(
    // ... all your existing fields including ExpirationDate: Date? = null
) : BaseMembership

4. Check Nullable & Val/Var Consistency

  • @Parcelize works with nullable fields, but ensure all non-null val fields (like PartnerMembershipId, Issuer, IsPartnerCard, Status) are always initialized when creating a MemberCard instance—they don’t have default values, so passing null here will throw an NPE.
  • If you’re seeing null-related exceptions, double-check that you’re not passing null to these required non-null fields.

5. Make Sure All Serialized Fields Are in the Primary Constructor

@Parcelize only serializes properties defined in the data class’s primary constructor. If you’ve added any properties outside of it (like in a secondary constructor or as class-level properties), they won’t be parcelized. Move any fields that need to be saved/restored into the primary constructor.

6. Test Parcelization Manually to Pinpoint the Issue

To figure out exactly which field is causing the problem, test parceling and unparceling directly in debug code or a unit test:

// Create a test instance of MemberCard
val testCard = MemberCard(
    PartnerMembershipId = 123,
    Issuer = "Coffee Shop Co.",
    IsPartnerCard = true,
    Status = "ACTIVE"
)

// Parcel the object
val parcel = Parcel.obtain()
testCard.writeToParcel(parcel, 0)
parcel.setDataPosition(0) // Reset parcel to read from the start

// Unparcel it
val unparceledCard = MemberCard.CREATOR.createFromParcel(parcel)

// Compare fields to spot inconsistencies
check(testCard.PartnerMembershipId == unparceledCard.PartnerMembershipId)
check(testCard.Issuer == unparceledCard.Issuer)
// Add checks for other fields to see which one breaks

This will help you isolate exactly which field is causing the exception (e.g., if ExpirationDate is the culprit, the check for that field will fail or throw an error).


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:34:01