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!
 
Top