Eggman87
Eggman87

Reputation: 571

Android Parcelable in Kotlin: CREATOR not found on Parcelable data class

With the release of the Kotlin RC, I started writing an app to learn it however I can not figure out how to get Parcelable to work.

the data class:

data class Project (val reponame:String,
                val username:String,
                val language:String,
                val vcsUrl:String,
                val branches:Map<String, Branch>) : Parcelable {

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

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

    protected constructor(parcelIn: Parcel) : this (
            parcelIn.readString(),
            parcelIn.readString(),
            parcelIn.readString(),
            parcelIn.readString(),
            mapOf<String, Branch>().apply {
                parcelIn.readMap(this, Branch::class.java.classLoader)
            }
    )

    override fun describeContents(): Int {
        throw UnsupportedOperationException()
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeString(reponame)
        dest.writeString(username)
        dest.writeString(language)
        dest.writeString(vcsUrl)
        dest.writeMap(branches)
    }

}

Reading it:

class ProjectDetailActivity : BaseActivity() {

    lateinit var project: Project

    companion object {
        const val EXTRA_PROJECT = "extra_project"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        project = intent.extras.getParcelable(EXTRA_PROJECT)

        tvTitle.text = project.reponame
    }
}

The exception:

Caused by: android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR on class com.eggman.circleciandroid.model.Project
    at android.os.Parcel.readParcelableCreator(Parcel.java:2415)
    at android.os.Parcel.readParcelable(Parcel.java:2337)
    at android.os.Parcel.readValue(Parcel.java:2243)
    at android.os.Parcel.readArrayMapInternal(Parcel.java:2592)
    at android.os.BaseBundle.unparcel(BaseBundle.java:221)
    at android.os.BaseBundle.get(BaseBundle.java:281)
    at com.eggman.circleciandroid.ui.ProjectDetailActivity.onCreate(ProjectDetailActivity.kt:22)

I am sure it is something simple I am missing, has anyone else had success with Parcelable on latest Kotlin?

Kotlin Version: 1.0.0-rc-1036

Kotlin Plugin Version: 1.0.0-rc-1036-IJ143-4

Code is viewable @ https://github.com/eggman87/circle-kotlin

Upvotes: 16

Views: 7798

Answers (2)

hotkey
hotkey

Reputation: 148129

Kotlin RC dropped previously deprecated generation of static fields for all companion object properties (learn more in this answer).

Now only those marked by const, lateinit or @JvmField will have a static field generated.

You need to annotate val CREATOR by @JvmField annotation since Android Framework expects a static field CREATOR in your class.

Upvotes: 29

Juan Saravia
Juan Saravia

Reputation: 7711

Here you have some useful Kotlin extension functions that will help you to create your CREATORs and also some examples (using data classes and list inside the data class)

Gist: Data Class & Parcelables example

I'm using this code in an Android App: (link)

The same code you can find it here: (link)

Upvotes: 1

Related Questions