Android Question R8 Optimizer breaking string-based reflection (JavaObject / Reflector)

Scantech

Well-Known Member
Licensed User
Longtime User
java.lang.RuntimeException: Field: player not found in: b0.d

B4X:
Private Sub SwitchTargetPlayerView(FullScreenIsDestination As Boolean)
    Dim mp As HalfScreen
    mp = B4XPages.GetPage("Media Player")
    Dim jo As JavaObject
    Dim Player As Object = mp.Player.As(JavaObject).GetField("player")  ' This line crashed!
    jo.InitializeStatic("androidx.media3.ui.PlayerView")
    jo.RunMethod("switchTargetView", Array(Player, IIf(FullScreenIsDestination, mp.SimpleExoPlayerView1, SimpleExoPlayerView1), IIf(FullScreenIsDestination, SimpleExoPlayerView1, mp.SimpleExoPlayerView1)))
End Sub

While testing B4A 14.20 Beta with R8 enabled, I ran into a runtime crash when using JavaObject to access fields or methods via string names (for example, getting an internal .player field or calling dynamic methods via reflection).

Because R8 is a static analyzer, it can't detect string literals passed to JavaObject, so it treats those fields/methods as unused, strips them, or obfuscates them (resulting in crashes like Field: player not found in: b0.d).

To prevent this for apps using reflection-heavy libraries (like Media3/ExoPlayer wrappers or custom Java objects), developers need to add explicit keep rules like this to their ProGuard configuration:

B4X:
-keepclassmembers class * {
    *** player;
}


Would it be worth adding a note or considering safer default ProGuard rules in the IDE template for common reflection patterns, so others don't hit unexpected obfuscation crashes when moving to R8?

Thanks!
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…