How to use Parcel.readTypedList() along with @Parcelize from kotlin-android-extensions?

偶尔善良 提交于 2019-12-04 04:35:17

问题


I'm running into a problem with implementing Parcelable-based state persistence in a View. Namely, as I need to implement the methods of BaseSavedState like this:

class SavedState : BaseSavedState {
    lateinit var myList: ArrayList<MyParcelable>

    constructor(superState: Parcelable) : super(superState) {}

    private constructor(parcel: Parcel) : super(parcel) {
        val listSize = parcel.readInt()
        val list = ArrayList<MyParcelable>(listSize)
        this.myList = parcel.readTypedList(list, /* needs MyParcelable.CREATOR */ )
    }

    override fun writeToParcel(out: Parcel, flags: Int) {
        super.writeToParcel(out, flags)
        out.writeInt(myList.size())
        out.writeTypedList(myList)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<SavedState> = object : Parcelable.Creator<SavedState> {
            override fun createFromParcel(`in`: Parcel): SavedState {
                return SavedState(`in`)
            }

            override fun newArray(size: Int): Array<SavedState?> {
                return arrayOfNulls(size)
            }
        }
    }
}

However, as you can see, I can't seem to use Parcel.readTypedList() because it needs both the typed list, and the parcelable's CREATOR field!

Classes marked like:

@Parcelize
data class MyParcelable(val someData: String): Parcelable {
}

Do not have CREATORs, in fact, if you try to implement, it says:

'CREATOR' definition is not allowed. Use 'Parceler' companion object instead.

I do not want a Parceler companion object, I need a CREATOR!

I also kinda don't want to write the Parcelable implementation by hand, so I might just make it Serializable and be like "whatever".


Does anyone know by chance how you can use Parcel.readTypedList() with @Parcelize-annotated Kotlin data class?


回答1:


It's a bug on the Parcelize plugin like you mentioned https://youtrack.jetbrains.com/issue/KT-19853 and it can be solved by either reflection or actually, you can have a proxy class to java as you can access that CREATOR field in java without any problems.

I made a util java class for all creators and then made a kotlin extension referring to that creator

Java

@NonNull
public static Parcelable.Creator<Blah> getBlahCreator() {
    return Blah.CREATOR;
}

Kotlin

val Blah.Companion.CREATOR: Parcelable.Creator<Blah>
 get() = UtilClass.getBlahCreator()

And now I can access Blah.CREATOR anywhere! And those two classes that have all the creators and extensions could be just deleted later after the bug got fixed in the foreseeable future and it'll just work as expected without any edits in the other classes that use the CREATOR

This feels much better to me than the reflection solution! but either way, they are both disgusting and I hope this bug could be fixed soon enough!



来源:https://stackoverflow.com/questions/51799353/how-to-use-parcel-readtypedlist-along-with-parcelize-from-kotlin-android-exte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!