0

In Android using koltin, having a base class Filters which is a Parceable. It works fine with it. Now need to have a derived class DerivedFilter which overrides the function of getIGenericHandler().

If do not implements its own parceable part, the override function will be deserialized back.

But when implement its parcelable part it got the complier error: "Primary constructor call expected" at

   constructor(parcel: Parcel) : super(parcel)

why it cannot call the super(parcel)?

tried a few and non of them worked (showing comment out in code).

How to derive a class from parcelable and implements its own parceable part?

tried similar with this, but does not work.

    open class Filters() : Parcelable {

        var streamType: String = ""
        // simplified it has map, list members

        constructor(streamTypeValue: String): this() {
           init(streamTypeValue)
        }

        constructor(parcel: Parcel) : this() {

            val streamTypeValue: String = parcel.readString()
            // simplified, it has map, list to build from the parcel

            init(streamTypeValue)
        }

        protected fun init(streamType: String) {

            this.streamType = streamType
            // simplified, it will pass in map, list to set to the corresponding members

        }

        open fun <T>getIGenericHandler(): IGenericHandler<IData<T>>? {
            return null
        }

        override fun describeContents(): Int {
            return 0
        }

        override fun writeToParcel(dest: Parcel, flags: Int) {

            dest.writeString(streamType)

        }

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

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



    }


    class DerivedFilter(streamType: String)
        : Filters (streamType){


        override fun <T>getIGenericHandler(): IGenericHandler<IData<T>>? {

            val h = GenericHandler(null, null)
            return h as IGenericDataHandler<IData<T>>
        }


        private constructor(parcel: Parcel) : super(parcel) {  //<=== got compiler error: "Primary constructor call expected"

        }

        /**
         * private constructor(parcel: Parcel) : this() {}  //<=== got compiler error:

        //None of the following functions can be called with the arguments supplied:
        //private constructor DerivedFilter(parcel: Parcel) defined in com.test.DerivedFilter
        //public constructor DerivedFilter(streamType: String)

         // if add
         constructor(): this(){}
         // got error: There's a cycle in the delegate calls chain
        */
        override fun writeToParcel(out: Parcel, flags: Int) {
            super.writeToParcel(out, flags)
        }

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

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

        override fun describeContents(): Int {
            return 0
        }

    }
lannyf
  • 9,865
  • 12
  • 70
  • 152

3 Answers3

0

Consider to use @Parcelize annotation instead implementing Parcelable interface yourself. With @Parcelize a Parcelable implementation will be generated automatically.

Andrew Churilo
  • 2,229
  • 1
  • 17
  • 26
0

you could use @Parcelize annotation with which you can save a lot of code for the implementation of Parcelable.

Setting up Kotlin Android Extensions

  1. The configuration of my gradle is the following:

Build.gradle // app

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' // Add this


androidExtensions {
  experimental = true // Add this
}

dependencies {
  implementation fileTree(dir: 'libs', include: ['*.jar'])

  // ------------------------- KOTLIN ------------------------- //
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11"

 ... // Other Dependencies

} 


@Parcelize
class Filters(var streamType: String = "") : Parcelable
Juanes30
  • 2,398
  • 2
  • 24
  • 38
0

this one works, maybe there is better ones?

    class DerivedFilter()
        : Filters (){


        override fun <T>getIGenericHandler(): IGenericHandler<IData<T>>? {

            val h = GenericHandler(null, null)
            return h as IGenericDataHandler<IData<T>>
        }

        constructor(streamType: String)
                : this () {

            init(streamType)

        }

        // calling into base::init(parcel)
        private constructor(parcel: Parcel) : this() {
            init(parcel)
        }

        override fun writeToParcel(out: Parcel, flags: Int) {
            super.writeToParcel(out, flags)
        }

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

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

        override fun describeContents(): Int {
            return 0
        }

    }
lannyf
  • 9,865
  • 12
  • 70
  • 152