Pit encountered by kotlin Parcelable, used by Parcelize

Keywords: Java Android Gradle

When we jump between pages, we often need to pass values. In Java, we implement the Parcelable interface and the response method. However, when using Kotlin, I encountered some problems, as follows:

problem

1. Create two activities, MainActivity and Main2Activity. Click the Button on MainActivity to jump to Main2Activity and pass our Bean.
2. Create MainActivity
Jump in MainActivity:

btn.setOnClickListener({
          val intent = Intent(this, Main2Activity::class.java)
          val user = User("jzd", 100)
          intent.putExtra("user", user)

          val bean = DispatchRecordBean("id", "plateNumber", "createTime", "reason", "startTime",
                  "endTime", "recipient", "model", "carColor", "carBrands", "carCategory", "carYear", 10)
          intent.putExtra("bean", bean)

          startActivity(intent)
      })

User object:

data class User(val name: String, val age: Int) : Parcelable
{
   constructor(parcel: Parcel) : this(
           parcel.readString(),
           parcel.readInt())
   {
   }

   override fun writeToParcel(parcel: Parcel, flags: Int)
   {
       parcel.writeString(name)
       parcel.writeInt(age)
   }

   override fun describeContents(): Int
   {
       return 0
   }

   companion object CREATOR : Parcelable.Creator<User>
   {
       override fun createFromParcel(parcel: Parcel): User
       {
           return User(parcel)
       }

       override fun newArray(size: Int): Array<User?>
       {
           return arrayOfNulls(size)
       }
   }
}

DispatchRecordBean object:

data class DispatchRecordBean(var id: String, var plateNumber: String, var createTime: String, var reason: String,
                              var startTime: String, var endTime: String, var recipient: String, var carModel: String, var carColor: String, var carBrands: String, var carCategory: String,
                              var carYear: String, var dispatchType: Int) : Parcelable
{
    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readString(),
            parcel.readInt())

    override fun writeToParcel(parcel: Parcel, flags: Int)
    {
        parcel.writeString(id)
        parcel.writeString(plateNumber)
        parcel.writeString(createTime)
        parcel.writeString(reason)
        parcel.writeString(startTime)
        parcel.writeString(endTime)
        parcel.writeString(recipient)
        parcel.writeString(carModel)
        parcel.writeString(carColor)
        parcel.writeString(carBrands)
        parcel.writeString(carCategory)
        parcel.writeString(carYear)
        parcel.writeInt(dispatchType)
    }

    override fun describeContents(): Int
    {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<DispatchRecordBean>
    {
        override fun createFromParcel(parcel: Parcel): DispatchRecordBean
        {
            return DispatchRecordBean(parcel)
        }

        override fun newArray(size: Int): Array<DispatchRecordBean?>
        {
            return arrayOfNulls(size)
        }
    }
}

3. Received in main2activity:

val user = intent.getParcelableExtra<User>("user")
mTvName.text = user?.name
mTvAge.text = user?.age.toString()

val bean = intent.getParcelableExtra<DispatchRecordBean>("bean")
mTvId.text = bean?.dispatchType.toString()

4. The problem is that my User object can pass values normally, but my Dispatch object can't.Debug look at the code and find that in the constructor method of the Dispatch class, the value of parcel.readString() is a jumping value. Normally, it should be based on ID - > plantnumber - > createtime - > reason - > starttime - > Endtime - > recipient - > carmodel - > carcolor - > carbrands - > carcategory Y - > caryear - > dispatchtype, and Debug found that the value obtained by parcel.readString() is ID - > createtime - > starttime - > recipient.. in this way, the value of the later fields can't be obtained. Did it take two values at a time? When modifying the Dispatch code, it was found that the value situation will change, it's really confused Up to now, I don't know what the situation is. It's better to transfer the value in the Parcelize mode to solve the problem.
Next, let's talk about how to pass values by Parcelize:

Parcelize transfer value

Add in the Module's build.gradle:

apply plugin: 'kotlin-android-extensions'
android
{
    androidExtensions {
        experimental = true
    }
}

Modify the Dispatch code and add the Parcelize annotation. Finally, the Dispatch code is as follows:

@SuppressLint("ParcelCreator")
@Parcelize
data class DispatchRecordBean(var id: String, var plateNumber: String, var createTime: String, var reason: String,
                              var startTime: String, var endTime: String, var recipient: String, var carModel: String, var carColor: String, var carBrands: String, var carCategory: String,
                              var carYear: String, var dispatchType: Int) : Parcelable

The problem is solved. For the moment, use the Parcelize annotation to transfer the value

Posted by asgerhallas on Sun, 05 Apr 2020 15:33:00 -0700