10

I have such Java parcelable:

@SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
    public KwerendaGraficzna createFromParcel(Parcel in) {
        return new KwerendaGraficzna(in);
    }

    public KwerendaGraficzna[] newArray(int size) {
        return new KwerendaGraficzna[size];
    }
};

Now trying to implement it in Kotlin:

companion object {
    @SuppressWarnings("rawtypes")
    val CREATOR: Parcelable.Creator<KwerendaGraficzna!> = object : Parcelable.Creator<KwerendaGraficzna!> {
        override fun createFromParcel(`in`: Parcel): KwerendaGraficzna {
            return KwerendaGraficzna(`in`)
        }

        override fun newArray(size: Int): Array<KwerendaGraficzna!> {
            return arrayOfNulls<KwerendaGraficzna!>(size)
        }
    }
}

arrayOfNulls won't compile requires KwerendaGraficzna while it claims it received KwerendaGraficzna?

So how do I do it?

ssuukk
  • 8,200
  • 7
  • 35
  • 47
  • Also see https://stackoverflow.com/questions/33551972/is-there-a-convenient-way-to-create-parcelable-data-classes-in-android-with-kotl – albert c braun Dec 05 '17 at 21:40

2 Answers2

17

I suspect you're using an outdated version of Kotlin compiler (since you use !). Here's a version compiling properly with latest version:

companion object {
    @JvmField
    val CREATOR = object : Parcelable.Creator<KwerendaGraficzna> {
        override fun createFromParcel(`in`: Parcel): KwerendaGraficzna {
            return KwerendaGraficzna(`in`)
        }

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

Since the Parcelable.Creator requires a public static field we need to mark the CREATOR property with @JvmField and JvmStatic.

miensol
  • 39,733
  • 7
  • 116
  • 112
  • Thanx, I will check it later. One question though - why does Kotlin require type specification where Java doesn't? – ssuukk Jan 10 '16 at 10:27
  • @ssuukk Not sure what you mean. Kotlin uses [declaration-site variance](https://kotlinlang.org/docs/reference/generics.html#declaration-site-variance) as opposed to use-site variance. – miensol Jan 10 '16 at 10:44
  • @miensol do you think this still works? I end up with a exception: Parcelable protocol requires a Parcelable.Creator object called CREATOR when trying to read from a bundle. – Eggman87 Feb 07 '16 at 04:55
  • 1
    @miensol thanks! Ended up asking a question and getting it answered here. Worth noting you only need the JvmField annotation for the CREATOR. – Eggman87 Feb 07 '16 at 18:58
  • @Eggman87 Just looked at the generated class and you're right. However it seems strange that the compiler generates a static field even though we did not instruct it to do so. – miensol Feb 07 '16 at 19:13
0

You don't need to implement all the boilerplate code.

Instead,

@Parcelize
data class KwerendaGraficzna(val a: Int, val b: String): Parcelable{
    // TODO: others code
}

That's it.

You need to enable experimental to true in build.gradle to apply the method above.

android{
    compileSdkVersion 30
    
    defaultConfig{
        applicationId "com.example"
        minSdkVersion 25
        targetSdkVersion 30
        ...
    }

    ...

    androidExtensions {
        experimental = true
    }
}
c-an
  • 3,543
  • 5
  • 35
  • 82