带有 libgdx 游戏的 Android 应用一旦在 Google Play 商店中发布,哪些 R8 规则是必要的?

Posted

技术标签:

【中文标题】带有 libgdx 游戏的 Android 应用一旦在 Google Play 商店中发布,哪些 R8 规则是必要的?【英文标题】:Which R8 rules are necessary to make an android app with a libgdx game work once published in the Google Play Store? 【发布时间】:2020-12-01 07:15:56 【问题描述】:

我正在尝试发布一个包含 libgdx 迷你游戏的 android 应用程序,在调试模式下应用 R8 (minifyEnabled true) 后它工作正常,但是当我在发布模式下执行它并在 Play 商店中发布它时,应用程序崩溃当我按下打开 libgdx 游戏的按钮时。我使用 Android Studio 4.0 版

我曾多次尝试使用不同的 R8 规则,但在生产环境中它们都不起作用。

我在 Android 模块中的代码:

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
            
         

片段中的按钮(取决于 MainActivity)启动 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)
    
 

核心模块中的代码:

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;
    

应用崩溃时我从 Google Play 控制台收到的错误是:

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

类型: java.lang.RuntimeException

堆栈跟踪:

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】:

问题跟踪器上有一个issue for this exact problem。要么你更新到 libgdx 1.9.11,要么你应该禁用 R8,直到你这样做。您可以改用 Proguard。

【讨论】:

我有 libgdx 版本 1.9.8,更新到 1.9.11 解决了这个问题。 @MrStahlgelge 解决方案解决了我的问题。

以上是关于带有 libgdx 游戏的 Android 应用一旦在 Google Play 商店中发布,哪些 R8 规则是必要的?的主要内容,如果未能解决你的问题,请参考以下文章

Android:LibGDX 2D游戏内存消耗

libGDX - Android Studio 中的 Google Play 游戏服务

Android游戏框架Libgdx使用入门

Libgdx 游戏在 Android 上崩溃

如何更改我的 android 游戏的图片/标志? - libGDX [重复]

开源java游戏框架libgdx专题-07-文件处理