Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserialization for list parcelable crashes when you call writeTypedList(null) first #30

Open
danielgomezrico opened this issue Nov 20, 2018 · 1 comment

Comments

@danielgomezrico
Copy link

Current generated code for list of parcelables will crash if you put an empty list.

Error example

Caused by: java.lang.IllegalStateException: source.createTypedArrayL…(AvatarUrlHolder.CREATOR) must not be null

Example code

class AvatarUrlHolder(val id: Long, val url: String) : Parcelable {

  constructor(source: Parcel) : this(source.readLong(), source.readString())

  override fun describeContents() = 0

  override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
    writeLong(id)
    writeString(url)
  }

  companion object {
    @JvmField
    val CREATOR: Parcelable.Creator<AvatarUrlHolder> = object : Parcelable.Creator<AvatarUrlHolder> {
      override fun createFromParcel(source: Parcel): AvatarUrlHolder = AvatarUrlHolder(source)
      override fun newArray(size: Int): Array<AvatarUrlHolder?> = arrayOfNulls(size)
    }
  }

}

// Class that have the list
class People(val avatars: List<AvatarUrlHolder>) : Parcelable {

  constructor(source: Parcel) : this(
    source.createTypedArrayList(AvatarUrlHolder.CREATOR)
  )

  override fun describeContents() = 0

  override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
    writeTypedList(agreedExpertsAvatars)
  }

  companion object {
    @JvmField
    val CREATOR: Parcelable.Creator<People> = object : Parcelable.Creator<People> {
      override fun createFromParcel(source: Parcel): People = People(source)
      override fun newArray(size: Int): Array<People?> = arrayOfNulls(size)
    }
  }
}

If you create the people with People(listOf()) the method writeTypedList will crash with:

Caused by: java.lang.IllegalStateException: source.createTypedArrayL…(AvatarUrlHolder.CREATOR) must not be null

Solution

This can be fixed if the generated code in the constructor looks like:

listOf<AvatarUrlHolder>().apply {
  source.readTypedList(this, AvatarUrlHolder.CREATOR)
}

instead of:

source.createTypedArrayList(AvatarUrlHolder.CREATOR)
danielgomezrico added a commit to danielgomezrico/android-parcelable-intellij-plugin-kotlin that referenced this issue Nov 20, 2018
@danielgomezrico
Copy link
Author

The issue is related to calling writeTypedList(null).

If we use the proposed solution the read will not crash but im not sure if its a good idea since you should not call writeTypedList(null) in the first place...

WDYT?

@danielgomezrico danielgomezrico changed the title Current list parcelable code crashes when the list is empty Deserialization for list parcelable crashes when you call writeTypedList(null) first Nov 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant