Как получить из класса, который является приемлемым - PullRequest
0 голосов
/ 11 апреля 2019

В Android используется колтин, имеющий базовый класс Filters, который является Parceable.Это работает хорошо с этим.Теперь нужно иметь производный класс DerivedFilter, который переопределяет функцию getIGenericHandler().

Если не реализует свою собственную партируемую часть, функция переопределения будет десериализована обратно.

Но когдаРеализуя свою парсеральную часть, он получил ошибку компилятора: "Primary constructor call expected" at

   constructor(parcel: Parcel) : super(parcel)

, почему он не может вызвать super(parcel)?

, попытался несколько, и ни одна из них не сработала (показаны комментариив коде).

Как извлечь класс из parcelable и реализовать свою собственную распознаваемую часть?

пробовал аналогично this , но не работает.

    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
        }

    }

Ответы [ 3 ]

0 голосов
/ 12 апреля 2019

вы можете использовать @Parcelize annotation, с помощью которого вы можете сохранить много кода для реализации Parcelable.

Настройка расширений Kotlin для Android

  1. Конфигурация моего gradle следующая:

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
0 голосов
/ 12 апреля 2019

это работает, может быть, есть и лучшие?

    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
        }

    }
0 голосов
/ 11 апреля 2019

Попробуйте использовать аннотацию @ Parcelize вместо реализации интерфейса Parcelable самостоятельно.При @Parcelize реализация Parcelable будет сгенерирована автоматически.

...