Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 777
Eggman87 Avatar asked Feb 07 '16 05:02

Eggman87


2 Answers

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.

like image 126
hotkey Avatar answered Sep 21 '22 04:09

hotkey


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)

like image 42
Juan Saravia Avatar answered Sep 20 '22 04:09

Juan Saravia