适用于 Kotlin 的 ProGuard:无法解析 JVM 签名
ProGuard for Kotlin: JVM signature cannot be resolved
激活 ProGuard 时,我收到以下似乎源于 Kotlin Reflect 的错误消息。
kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Property 'selectedAccount' (JVM signature: getSelectedAccount()Lmy/app/package/data/model/Account;) not resolved in class my.app.package.data.SharedPrefsData
at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.findPropertyDescriptor(:115)
at kotlin.reflect.jvm.internal.KPropertyImpl$_descriptor.invoke(:102)
at kotlin.reflect.jvm.internal.KPropertyImpl$_descriptor.invoke(:27)
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(:92)
at kotlin.reflect.jvm.internal.KPropertyImpl.getDescriptor(:105)
at kotlin.reflect.jvm.internal.KPropertyImpl$_javaField.invoke(:52)
at kotlin.reflect.jvm.internal.KPropertyImpl$_javaField.invoke(:27)
at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(:62)
at kotlin.reflect.jvm.internal.KPropertyImpl.getJavaField(:79)
at kotlin.reflect.jvm.ReflectJvmMapping.getJavaField(:40)
at kotlin.reflect.jvm.KCallablesJvm.a(:65)
at com.chibatching.kotpref.livedata.KotprefLiveDataExtensionsKt$a.<init>(:16)
at com.chibatching.kotpref.livedata.KotprefLiveDataExtensionsKt.a(:11)
at my.app.package.data.SharedPrefsData.getSelectedAccountLiveData(:20)
SharedPrefsData
是一个简单的 KotprefModel 来存储和从 SharedPreferences 加载:
class SharedPrefsData(context: Context) : KotprefModel(context), ISharedPrefsData {
override val kotprefName: String = "${context.packageName}_preferences_data"
override var selectedAccount by gsonNullablePref<Account>()
override fun getSelectedAccountLiveData(): LiveData<Account?> {
return asLiveData(this::selectedAccount)
}
}
这就是 KotprefLiveDataExtensionsKt
中发生的事情
fun <T> KotprefModel.asLiveData(property: KProperty0<T>): LiveData<T> {
return object : LiveData<T>(), SharedPreferences.OnSharedPreferenceChangeListener {
private val key: String
init {
value = property.get()
property.isAccessible = true
key = (property.getDelegate() as? PreferenceKey)?.key ?: property.name
property.isAccessible = false
}
override fun onSharedPreferenceChanged(prefs: SharedPreferences, propertyName: String) {
if (propertyName == key) {
postValue(property.get())
}
}
override fun onActive() {
this@asLiveData.preferences.registerOnSharedPreferenceChangeListener(this)
}
override fun onInactive() {
this@asLiveData.preferences.unregisterOnSharedPreferenceChangeListener(this)
}
}
}
所以似乎有一些 Kotlin Reflection 正在进行,这会导致 ProGuard 出现问题。
但是我已经保留了涉及的模型 类 以及 SharedPrefsData 类。我在 KotPref Github 上找到的唯一 ProGuard 规则已在此处应用。
现在我正在使用以下 ProGuard 规则:
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class kotlin.reflect.jvm.ReflectJvmMapping { *; }
-keep class com.chibatching.kotpref.livedata.KotprefLiveDataExtensionsKt
-keep class kotlin.reflect.jvm.KCallablesJvm
-keep class my.app.package.data.model.Account { *; }
-keep class my.app.package.data.model.User { *; }
-keep class my.app.package.data.model.Team { *; }
-keep class my.app.package.data.SharedPrefsData { *; }
-keep class my.app.package.data.ISharedPrefsData { *; }
但是错误依然存在。知道在这里做什么吗??
虽然错误确实源于假设的 kotlin 反射问题,但我通过更新到最新的 Kotpref 版本 2.10.0 解决了这个问题
此版本不再使用反射,proguard 规则已过时。
激活 ProGuard 时,我收到以下似乎源于 Kotlin Reflect 的错误消息。
kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Property 'selectedAccount' (JVM signature: getSelectedAccount()Lmy/app/package/data/model/Account;) not resolved in class my.app.package.data.SharedPrefsData
at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.findPropertyDescriptor(:115)
at kotlin.reflect.jvm.internal.KPropertyImpl$_descriptor.invoke(:102)
at kotlin.reflect.jvm.internal.KPropertyImpl$_descriptor.invoke(:27)
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(:92)
at kotlin.reflect.jvm.internal.KPropertyImpl.getDescriptor(:105)
at kotlin.reflect.jvm.internal.KPropertyImpl$_javaField.invoke(:52)
at kotlin.reflect.jvm.internal.KPropertyImpl$_javaField.invoke(:27)
at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(:62)
at kotlin.reflect.jvm.internal.KPropertyImpl.getJavaField(:79)
at kotlin.reflect.jvm.ReflectJvmMapping.getJavaField(:40)
at kotlin.reflect.jvm.KCallablesJvm.a(:65)
at com.chibatching.kotpref.livedata.KotprefLiveDataExtensionsKt$a.<init>(:16)
at com.chibatching.kotpref.livedata.KotprefLiveDataExtensionsKt.a(:11)
at my.app.package.data.SharedPrefsData.getSelectedAccountLiveData(:20)
SharedPrefsData
是一个简单的 KotprefModel 来存储和从 SharedPreferences 加载:
class SharedPrefsData(context: Context) : KotprefModel(context), ISharedPrefsData {
override val kotprefName: String = "${context.packageName}_preferences_data"
override var selectedAccount by gsonNullablePref<Account>()
override fun getSelectedAccountLiveData(): LiveData<Account?> {
return asLiveData(this::selectedAccount)
}
}
这就是 KotprefLiveDataExtensionsKt
fun <T> KotprefModel.asLiveData(property: KProperty0<T>): LiveData<T> {
return object : LiveData<T>(), SharedPreferences.OnSharedPreferenceChangeListener {
private val key: String
init {
value = property.get()
property.isAccessible = true
key = (property.getDelegate() as? PreferenceKey)?.key ?: property.name
property.isAccessible = false
}
override fun onSharedPreferenceChanged(prefs: SharedPreferences, propertyName: String) {
if (propertyName == key) {
postValue(property.get())
}
}
override fun onActive() {
this@asLiveData.preferences.registerOnSharedPreferenceChangeListener(this)
}
override fun onInactive() {
this@asLiveData.preferences.unregisterOnSharedPreferenceChangeListener(this)
}
}
}
所以似乎有一些 Kotlin Reflection 正在进行,这会导致 ProGuard 出现问题。 但是我已经保留了涉及的模型 类 以及 SharedPrefsData 类。我在 KotPref Github 上找到的唯一 ProGuard 规则已在此处应用。
现在我正在使用以下 ProGuard 规则:
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class kotlin.reflect.jvm.ReflectJvmMapping { *; }
-keep class com.chibatching.kotpref.livedata.KotprefLiveDataExtensionsKt
-keep class kotlin.reflect.jvm.KCallablesJvm
-keep class my.app.package.data.model.Account { *; }
-keep class my.app.package.data.model.User { *; }
-keep class my.app.package.data.model.Team { *; }
-keep class my.app.package.data.SharedPrefsData { *; }
-keep class my.app.package.data.ISharedPrefsData { *; }
但是错误依然存在。知道在这里做什么吗??
虽然错误确实源于假设的 kotlin 反射问题,但我通过更新到最新的 Kotpref 版本 2.10.0 解决了这个问题
此版本不再使用反射,proguard 规则已过时。