Search code examples
androidkotlinparcelable

Passing parcelized Kotlin data class from activity to activity does not persits data


I tried to pass a class between activities using parcelize. For this I got A class which has other classes as members:

@Parcelize
class Entry(var uid_sensor: String = "No-Id", val firstConfig: fConfig= fConfig(), val SecondConfig: sConfig = sConfig(),
   ...) : Parcelable { ... }

where e. g. fConfig is given by

@Parcelize
data class fConfig(val swVersion: UInt8 = UInt8("swStructVersion" ), val fwVersion: UInt32 = UInt32("fwVersion"),
    ...) : ConfigStructure(), Parcelable { ... }

and UInt8, UInt32 are as well custom classes, e. g.:

@Parcelize
data class UInt8(override val name: String,  override val size: Int = 1, override val readOnly: Boolean = true) : DataField, Parcelable {
    var value: UByte? = 0.toUByte() // Here we init the value with zeros.
    ... // Some more parameters
}

@Parcelize
data class UInt32(override val name: String, override val size: Int = 1, override val readOnly: Boolean = true) : DataField, Parcelable {
    var value: UInt? = 0.toUInt() // Here we init the value with zeros.
    ... // Some more parameters
}

Note, that these classes are initialized with zeros!


Although I've marked each of this class as parcelable, I cannot pass the object correctly. If I try to return a Entry-Object from an Activity to the MainActivity like this

val returnIntent = Intent()
returnIntent.putExtra(Constants.ActivityDataPassing.SENSOR, newEntry)
setResult(RESULT_OK, returnIntent)
finish()

and capture it in the MainActivity like this:

val intentLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->

            if (result.resultCode == Activity.RESULT_OK) {
                val sen : SensorEntry = result.data?.extras?.getParcelable<Entry>(Constants.ActivityDataPassing.SENSOR) as Entry
                sensor_list?.add(sen)
                ...
            }
        }

the members of the classes firstConfig and secondConfig have zeros instead the values I have set. Why is this and why are my data not passed correctly? Is there a better way to share such objects between activities?


To make this behavior more clear, I've appended a screenshot of the very same object before and after passing. Illustration


Solution

  • From - developer.android.com

    @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.

    Therefore, this fixes it:

    @Parcelize
    data class UInt32(
       override val name: String, 
       override val size: Int = 1, 
       override val readOnly: Boolean = true, 
       var value: UInt? = 0.toUInt()
    ) : DataField, Parcelable {
         // Here we init the value with zeros.
        ... // Some more parameters
    }