Search code examples
androidkotlinandroid-intentparcelabledata-class

Parcelable isn't working properly in kotlin


I send sendData from StartActivity to ResultActivity.

val sendData = SendData(10, "xyz", "yss")
sendData.e = 933
sendData.f = "hello"
sendData.g = 39

// Log.d("A", "${sendData.toString}")
val intent = Intent(this@StartActivity, ResultActivity::class.java)
intent.putExtra(RESULT_DATA, sendData)
startActivity(intent)
sendData = intent.extras!!.getParcelable(RESULT_DATA)
// Log.d("B", "${sendData.toString}")

The model class looks like this.

@Parcelize
data class SendData(var a: Int, var b: String, var c: String) : Parcelable {
    var e: Int? = null
    var f: String? = null
    var g: Int? = null
    
    var isClicked = false

    override fun toString(): String{
        return JsonUtil.toJson(this) // custom util
    }
}

But when I check the Log-A, Log-B.

// Log-A
{
   "a": 10,
   "b": "xyz",
   "c": "yss",
   "e": 933,
   "f": "hello",
   "g": 39,
   "isClicked": false
}

// Log-B
{
   "a": 10,
   "b": "xyz",
   "c": "yss",
   "isClicked": false
}

So, the members which is defined as Nullable are null after being passed. What's the problem of this code?


Solution

  • The way that @Parcelize works is that it only serializes/deserializes the properties in the primary constructor. You've only declared properties a, b and c in the primary constructor. Therefore, the compiler will only insert the values of a, b and c into the generated Parcel and, of course, only these values will be unmarshalled at the receiving end.

    You need to add the other properties to your primary constructor, or implement the Parcelable interface yourself instead of using @Parcelize.

    See https://joaoalves.dev/posts/kotlin-playground/parcelable-in-kotlin-here-comes-parcelize/

    See also this question and the various suggestions in the answers