Отражение DelegatedProperty не работает при сборке выпуска

Во время выполнения мне нужно получить доступ к свойствам в экземпляре делегата делегированного свойства.

Когда я компилирую следующий код при отладке, он работает нормально:

class Potato {
    val somePropGoesHere: Int by PotatoDeletgate("This is the key", 0)

    fun getKey(property: KProperty1<Potato, *>): String {
        property.isAccessible = true
        val delegate = property.getDelegate(this)

        return when (delegate) {
            is PotatoDeletgate<*> -> delegate.key
            else -> throw IllegalStateException("Can't observe the property - ${property.name}")
        }
    }

    class PotatoDeletgate<T>(val key: String,
                             defaultValue: T) {
        private var innerValue = defaultValue

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
            // more logic
            return innerValue
        }

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            // more logic
            innerValue = value
        }
    }
}

class PotatoShredder {
    fun doStuff() {
        val potato = Potato()
        val key = potato.getKey(Potato::somePropGoesHere)
    }
}

Когда я вызываю метод "doStuff" при отладке, "key" val получит строку "This is the key".

Однако когда я компилирую этот код в выпуске, я получаю ошибку:

2019-11-07 16:16:04.141 7496-7496/? E / Android Время выполнения: ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основной процесс: com.trax.retailexecution, PID: 7496

eaaaj0: Свойство somePropGoesHere (подпись JVM: getSomePropGoesHere()I) не разрешено в классе com.trax.retailexecution.util.Potato

в eaaapc(KDeclarationContainerImpl.kt:40)

в eaaaz$d.invoke(KPropertyImpl.kt:4)

на eaaal0.a(ReflectProperties.java:4)

в eaaaze(KPropertyImpl.kt:2)

Я не уверен как

в eaaaz$e.invoke(KPropertyImpl.kt:1)

на eaaam0.a(ReflectProperties.java:3)

в eaaazi(KPropertyImpl.kt:1)

в cmabaa(DefaultConfigurationFactory.java:82)

в cmabaa(DefaultConfigurationFactory.java:153)

в com.trax.retailexecution.util.Potato.getKey(Potato.kt:1)

в mynamespacegoeshere.PotatoShredder.doStuff(Potato.kt:2)

Я думал, что это как-то связано с proguard, поскольку класс и / или методы мы удаляем во время сжатия / сжатия, но я не мог найти способ правильно решить проблему.

1 ответ

Он действительно связан с proguard - ваш somePropGoesHere не может быть найден в обфусцированном коде.

У меня нет никакого обходного пути, за исключением того, что не используется отражение:)(и я бы предложил это)

Вы также можете добавить своего PotatoDelegate в правила защиты:)

Ура!

Другие вопросы по тегам