Kotlin getParcelableArray from intent bundle not able to cast it to custom type
Asked Answered
M

3

9

I am running into a weird problem . I have a class A which implements Parcelable interface in kotlin.

I am passing the array of class A from one activity to another no issues here.

 var arrayOfA:Array<A> // just to tell the type assume the array is initialised with the value
 intent.putExtra("array", arrayOfA)

But while receiving it in another activity , I am not able to assign it to variable of type Array it is asking me to assign it to Array when A is on type parcelable why I am not able to assign it the variable.

in second Activity 
var arrayOfA:Array<A>?=null


arrayA=intent.get("array") as Array<A> // Problem here. Class cast exception

I am not able to understand why. Can some one help me here. I don't want to change the type of variable to Array as it as many inter depedencies.(The class here is just a demonstration)

========================================

class A(val a:String?,val b:String?):Parcelable {
    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readString()) {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(a)
        parcel.writeString(b)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<A> {
        override fun createFromParcel(parcel: Parcel): A {
            return A(parcel)
        }

        override fun newArray(size: Int): Array<A?> {
            return arrayOfNulls(size)
        }
    }
}
Monseigneur answered 12/9, 2017 at 5:54 Comment(2)
You really need to add class A to the question. Without it it's very hard to answerBaptista
Please see editMonseigneur
U
14

I ran into the same problem. This is how I was able to workaround it:

arrayOfA = intent.getParcelableArrayExtra("array").map { it as A }.toTypedArray()

For some reason this does not work:

arrayOfA = intent.getParcelableArrayExtra("array") as Array<A>

That unfortunately exhibits a warning

Unchecked cast: Array<(out) Parcelable!>! to Array)

and runtime exception

java.lang.ClassCastException: android.os.Parcelable[] cannot be cast to com.company.app.A[]

Uvula answered 29/5, 2019 at 21:27 Comment(1)
But why is this happening do you know @JordanH?Shavonda
D
8

Bundle.getParcelableArray (and Intent.getParcelableArrayExtra) return Parcelable[]. You can't cast Parcelable[] as MyClass[]. You can cast an element of Parcelable[] as MyClass.

Use Bundle.getParcelableArrayList (or its Intent counterpart) instead, because it has a generic type.

var values: List<MyClass> = listOf(...)
intent.putParcelableArrayListExtra("key", values.asArrayList())
values = intent.getParcelableArrayListExtra("key")!!

fun <E> List<E>.asArrayList(): ArrayList<E> = this as? ArrayList<E> ?: ArrayList(this)
Dannadannel answered 29/5, 2019 at 21:45 Comment(0)
H
2

You need to use getParcelableArrayExtra to retrieve Parcelable objects as in

arrayA = intent.getParcelableArrayExtra("array") as Array<A?>

Make class A as Nullable all over, because you can't cast Nullable to Non Nullable in Kotlin

creator should be like below

companion object CREATOR : Parcelable.Creator<A?> {
        override fun createFromParcel(parcel: Parcel): A? {
            return A(parcel)
        }

        override fun newArray(size: Int): Array<A?> {
            return arrayOfNulls(size)
        }
    }
Hilarity answered 12/9, 2017 at 6:1 Comment(4)
Even If I do it , I am getting classcastexpection. Cannot case Parcelable[] to A[]Monseigneur
could you paste your stack trace?Hilarity
java.lang.ClassCastException: android.os.Parcelable[] cannot be cast to A[]Monseigneur
let me try this and let you knowMonseigneur

© 2022 - 2024 — McMap. All rights reserved.