Parcelable isn't working properly in kotlin

1k Views Asked by At

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?

2

There are 2 best solutions below

0
On BEST ANSWER

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

0
On

@Parcelize requires all serialized properties to be declared in the primary constructor. The plugin issues a warning on each property with a backing field declared in the class body. Also, you can't apply @Parcelize if some of the primary constructor parameters are not properties.

From https://developer.android.com/kotlin/parcelize You must move e, f, and g variable declaration to primary constructor Your model code can be like this:

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

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