Crash in release builds: java.lang.NullPointerException: null cannot be cast to non-null type skip.ui.PreferenceKeyCompanion<Value of skip.ui.Preference>
marcprux opened this issue · comments
When the release Showcase.apk
in the emulator that uses a PreferenceKey
, crashes may occur like:
02-17 23:01:30.001 2470 2470 E AndroidRuntime: FATAL EXCEPTION: main
02-17 23:01:30.001 2470 2470 E AndroidRuntime: Process: skip.showcase.App, PID: 2470
02-17 23:01:30.001 2470 2470 E AndroidRuntime: java.lang.NullPointerException: null cannot be cast to non-null type skip.ui.PreferenceKeyCompanion<Value of skip.ui.Preference>
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at ra.e3.<init>(SourceFile:2)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at ra.e3.<init>(SourceFile:3)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at ra.u2$i.a(Unknown Source:765)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at ra.u2$i.p0(Unknown Source:10)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at s0.b.e(Unknown Source:49)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at s0.b.p0(Unknown Source:8)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at androidx.compose.material3.g2$d$a$a.a(Unknown Source:125)
02-17 23:01:30.001 2470 2470 E AndroidRuntime: at androidx.compose.material3.g2$d$a$a.q0(Unknown Source:8)
This is likely coming from PreferenceKey.swift
:
self.initialValue = initialValue ?? (key.companionObjectInstance as! PreferenceKeyCompanion<Value>).defaultValue
This seems to be a consequence of the release build's proguard reduction. Changing the Android/app/proguard-rules.pro
file to exclude skip classes makes the crash go away:
-keep class skip.** { *; }
-keep class showcase.module.** { *; }
However, it also increases the Showcase-release.apk
size to 15.5 MB from 11.1 MB. Similarly, HelloSkip-release.apk
jumps from 6.2 MB to 11 MB, which is an undesirable increase in minimum app size.
I suspect this is due to the way kotlin.reflect.full.companionObjectInstance
works. I wonder if it would be possible to avoid using reflection to get the companion object, maybe by using @JvmStatic
instead.
Some hints from Kotlin/kotlinx.serialization#1129 and Kotlin/kotlinx.serialization#1121 could yield a narrower set of proguard rules might work around this issue