Search code examples
androidkotlinandroid-intentbundleparcelable

Parcelable: Class not found when unmarshalling when calling from different App


I am trying to pass in a bundle from App1 with some data which its data class is Auxiliar to an App2 which also has defined Auxiliar data class but I get the following error:

E/Parcel: Class not found when unmarshalling: com.opp.App1.ui.main.Auxiliar

I think that App2 is trying to find Auxiliar definition when retrieving bundle info and I don't know how to say to use Auxiliar defined in App2

Here is some code

@Parcelize
data class Auxiliar(
    var nightId: Long = 0L,

    val startTimeMilli: Long = System.currentTimeMillis(),

    var endTimeMilli: Long = startTimeMilli,

    var quality: Int = -1
): Parcelable

App1

var intent: Intent? = activity?.packageManager?.getLaunchIntentForPackage("com.opp.App2")

val argu1 = Auxiliar(-101, 1,1,-1)
if (intent != null) {
            var bundle = Bundle()
            bundle.putParcelable("una", argu1)
            intent.putExtra("myBundle",bundle)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
}

Retrieve in App2:


val bundle = activity?.intent?.getBundleExtra("myBundle")
if (bundle != null) {
    var una = bundle.getParcelable<Auxiliar>("una")
    }

Solution

  • You cannot pass parcelable class from one app to another?

    Yes, you can. However, they have to be the same class. In other words, they need to have:

    • The same base name (Auxiliar)
    • The same package name (com.opp.App1.ui.main)
    • The same fields

    In your case, I am guessing that the package name is different. If you use the same package name in both apps — such as having both apps share a common library module that defines the class — then you will be in somewhat better shape.

    However, bear in mind that users do not need to update App1 and App2 at the same time. Parcelable is designed for use by framework classes, ones that are part of the firmware, where App1 and App2 are guaranteed to have the same implementation. If App1 has an old Auxiliar and App2 has a new Auxiliar, you may run into problems.

    You can only pass primitive classes?

    Passing anything that is defined in the Android SDK as Parcelable is safe, because App1 and App2 will have the same class definition for those classes. So, for example, Bundle is Parcelable. You would still need a versioning system to deal with data changes, but at least you are in control over how to handle that.