https://kotlinlang.org logo
#android
Title
# android
u

540grunkspin

02/21/2019, 8:55 AM
Does anyone know if there is a place to submit feature requests for ktx. I have been thinking about
Parcel.readSparseArray
. It returns
SparseArray
without any generic parameter and I am not aware of a way to read it with the generic parameter. It should be fairly easy to reify that one to do a cast for you. I know that this is not something that is super hard to do yourself but it feels like a hack every time i need to suppress the unchecked cast warning.
g

gildor

02/21/2019, 8:59 AM
but it feels like a hack every time i need to suppress the unchecked cast warning
You also can write extension function to encapsulate this behavior
u

540grunkspin

02/21/2019, 9:03 AM
Yeah sure I can. I was thinking that the goal of ktx was to reduce boilerplate and this is something that I find myself doing in nearly every project
g

gildor

02/21/2019, 9:03 AM
Yeah, sure, you may report
A problem that this function is always unsafe and this cast actually do not check items type, so your code may crash in some unexpected place trying to use this collection
For sure such function also may validate items, but probably it’s overkill for most use cases
u

540grunkspin

02/21/2019, 9:06 AM
Yeah maybe slap on an
@Trows
annotation. Or return a
SparseArray?
g

gildor

02/21/2019, 9:07 AM
No, you didn’t get what I mean
also
@Throws
is useless, this annotation make sense only for Java interop
u

540grunkspin

02/21/2019, 9:08 AM
True. But do you mean that the code can succeed the cast but crash when accessing the items?
g

gildor

02/21/2019, 9:11 AM
see:
Copy code
val input = SparseArray<Any>()
input.put(0, "String!") // Put string
a.writeSparseArray(input)
val output = a.readSparseArray(javaClass.classLoader) as SparseArray<Int> // No exception here!
val item: Int = output.get(0) // Exception will happen here!
if you extract
a.readSparseArray(javaClass.classLoader) as SparseArray<Int>
to function this function will return successfully, but cast will fail
u

540grunkspin

02/21/2019, 9:13 AM
Oh this was news to me but I guess it make sense since type erasure.
g

gildor

02/21/2019, 9:13 AM
Yes
u

540grunkspin

02/21/2019, 9:14 AM
Yeah then maybe I will just have to continue adding an extension and name it something like
readUncheckedSparseArray
g

gildor

02/21/2019, 9:22 AM
You can try to write something like that:
Copy code
inline fun <reified T> Parcel.readAndCastSparseArray(): SparseArray<T>? {
    val sparseArray = readSparseArray(javaClass.classLoader) ?: return null
    for (index in 0 until sparseArray.size()) {
        val value = sparseArray.valueAt(index)
        if (value != null && value !is T) {
            throw ClassCastException("Value $value on index $index cast failed to ${T::class}")
        }
    }
    @Suppress("UNCHECKED_CAST")
    return sparseArray as SparseArray<T>
}
CAREFUL, NOT TESTED
just an idea
u

540grunkspin

02/21/2019, 10:24 AM
Looks cool! Will for sure give it a try!
2 Views