Which R8 rules are necessary to make an android app with a libgdx game work once published in the Google Play Store?

Viewed 209

I am trying to publish an android app that includes a libgdx minigame, it works fine after appliying R8 (minifyEnabled true) in debug mode, but when I do it in release mode and publish it in the Play Store, the app crashes when I press the button that opens the libgdx game. I use Android Studio version 4.0

I have tryed several times with different R8 rules, but none of them works when on production.

My code in the Android Module:

build.gradle(:android)

        debug {
            minifyEnabled true 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

proguard-rules.pro

-verbose

-dontwarn android.support.**
-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
-dontwarn com.badlogic.gdx.utils.GdxBuild
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
-dontwarn com.badlogic.gdx.graphics.g2d.freetype.FreetypeBuild




#-keep class com.badlogic.gdx.controllers.android.AndroidControllers
# tried changing AndroidControllers with line:
-keep class com.badlogic.gdx.controllers.android.*

# tried adding this one
#-keep class com.ongngo.game.AndroidLauncher  

#    -keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
#       <init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
#    }

# tried separating AndroidInputs
    -keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput {
       <init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
    }
    -keepclassmembers class com.badlogic.gdx.backends.android.AndroidInputThreePlus {
       <init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
    }

# tried with this
-keepclassmembers class com.ongngo.game.CoreAndroidInterface
-keepclassmembers class com.ongngo.game.AndroidLauncher
-dontwarn com.badlogic.gdx.**
-dontnote com.badlogic.gdx.**
-keepclassmembers class com.badlogic.gdx.graphics.Cubemap* { *; }
-keepclassmembers class com.badlogic.gdx.graphics.GL* { *; }
#


-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
   boolean contactFilter(long, long);
   void    beginContact(long);
   void    endContact(long);
   void    preSolve(long, long);
   void    postSolve(long, long);
   boolean reportFixture(long);
   float   reportRayFixture(long, float, float, float, float, float);
}

MainActivity.kt:

onCreate(...) 
        ...
        coreAndroidInterface = object : CoreAndroidInterface {
            override fun updateLifes(lifes: Int) {
                var lifesVar = lifes
                if (lifes < 0) {
                    lifesVar = 0
                }

                MainActivity.LIFES = lifesVar
                prefs.lifes = lifesVar
            }
        } 

a Button in a fragment (depending of MainActivity) starts AndroidLauncher.k:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val config = AndroidApplicationConfiguration()
        config.useAccelerometer = false
        config.useCompass = false
        initialize(MyGame(MainActivity.LIFES!!, MainActivity.coreAndroidInterface), config)
    }
} 

Code in the Core module:

CoreAndroidInterface.kt

interface CoreAndroidInterface {
    fun updateLifes(lifes : Int)
} 

MyGame.java

public class MyGame extends Game implements ApplicationListener {
private final CoreAndroidInterface coreAndroidInterface;
...
    public MyGame(int vidas, CoreAndroidInterface coreAndroidInterface) {//constructor
        this.LIFES = lifes;
        this.coreAndroidInterface = coreAndroidInterface;
    }

The errors I get from the Google Play Console when the app crashes are:

 java.lang.ClassNotFoundException
com.ongngo.game.AndroidLauncher.onCreate 

Type: java.lang.RuntimeException

Stacktrace:

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2795)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2873)
  at android.app.ActivityThread.-wrap11 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1602)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6543)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
Caused by: java.lang.RuntimeException: 
  at com.badlogic.gdx.backends.android.AndroidInputFactory.newAndroidInput (AndroidInputFactory.java:65)
  at com.badlogic.gdx.backends.android.AndroidApplication.init (AndroidApplication.java:34)
  at com.badlogic.gdx.backends.android.AndroidApplication.initialize (AndroidApplication.java:1)
  at com.ongngo.game.AndroidLauncher.onCreate (AndroidLauncher.java:36)
  at android.app.Activity.performCreate (Activity.java:7023)
  at android.app.Activity.performCreate (Activity.java:7014)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1215)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2748)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2873)
  at android.app.ActivityThread.-wrap11 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1602)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6543)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
Caused by: java.lang.ClassNotFoundException: 
  at java.lang.Class.classForName (Class.java)
  at java.lang.Class.forName (Class.java:453)
  at java.lang.Class.forName (Class.java:378)
  at com.badlogic.gdx.backends.android.AndroidInputFactory.newAndroidInput (AndroidInputFactory.java:8)
  at com.badlogic.gdx.backends.android.AndroidApplication.init (AndroidApplication.java:34)
  at com.badlogic.gdx.backends.android.AndroidApplication.initialize (AndroidApplication.java:1)
  at com.ongngo.game.AndroidLauncher.onCreate (AndroidLauncher.java:36)
  at android.app.Activity.performCreate (Activity.java:7023)
  at android.app.Activity.performCreate (Activity.java:7014)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1215)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2748)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2873)
  at android.app.ActivityThread.-wrap11 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1602)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6543)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
Caused by: java.lang.ClassNotFoundException: 
  at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:125)
  at java.lang.ClassLoader.loadClass (ClassLoader.java:379)
  at java.lang.ClassLoader.loadClass (ClassLoader.java:312)
  at java.lang.Class.classForName (Class.java)
  at java.lang.Class.forName (Class.java:453)
  at java.lang.Class.forName (Class.java:378)
  at com.badlogic.gdx.backends.android.AndroidInputFactory.newAndroidInput (AndroidInputFactory.java:8)
  at com.badlogic.gdx.backends.android.AndroidApplication.init (AndroidApplication.java:34)
  at com.badlogic.gdx.backends.android.AndroidApplication.initialize (AndroidApplication.java:1)
  at com.ongngo.game.AndroidLauncher.onCreate (AndroidLauncher.java:36)
  at android.app.Activity.performCreate (Activity.java:7023)
  at android.app.Activity.performCreate (Activity.java:7014)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1215)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2748)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2873)
  at android.app.ActivityThread.-wrap11 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1602)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6543)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:807)
1 Answers

There is an issue for this exact problem on the issue tracker. Either you update to libgdx 1.9.11, or you should disable R8 until you do. You can use Proguard instead.

Related