LibGdx [致命异常] 加载一个皮肤 .json 文件

4
我正在使用Intellij。一切都正常,APK已在我的Android设备上部署,但只有黑屏,然后返回主屏幕,并提示“游戏已停止”。
    1023-1051/? E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 1591
Process: net.mygdx.game.android, PID: 1023
com.badlogic.gdx.utils.ax: Error reading file: jsonSkin.json
        at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
        at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
        at net.mygdx.game.a.a(Unknown Source)
        at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
 Caused by: com.badlogic.gdx.utils.ax: Error reading file: skins/jsonSkin.json
        at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
            at org.mygdx.gam.a.a(Unknown Source)
            at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
 Caused by: com.badlogic.gdx.utils.ax:
        at com.badlogic.gdx.e.a.a.k.a(Unknown Source)
        at com.badlogic.gdx.e.a.a.k.b(Unknown Source)
        at com.badlogic.gdx.utils.k.a(Unknown Source)
        at com.badlogic.gdx.e.a.a.j.a(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
            at net.mygdx.game.a.a(Unknown Source)
            at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
 Caused by: com.badlogic.gdx.utils.b.e: Class not found: com.badlogic.gdx.graphics.g2d.BitmapFont
        at com.badlogic.gdx.utils.b.b.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.b(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.j.a(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
            at net.mygdx.game.a.a(Unknown Source)
            at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
 Caused by: java.lang.ClassNotFoundException: com.badlogic.gdx.graphics.g2d.BitmapFont
        at java.lang.Class.classForName(Native Method)
        at java.lang.Class.forName(Class.java:251)
        at java.lang.Class.forName(Class.java:216)
            at com.badlogic.gdx.utils.b.b.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.b(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.j.a(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
            at net.mygdx.game.a.a(Unknown Source)
            at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
 Caused by: java.lang.NoClassDefFoundError: com/badlogic/gdx/graphics/g2d/BitmapFont
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:251)
            at java.lang.Class.forName(Class.java:216)
            at com.badlogic.gdx.utils.b.b.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.b(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.j.a(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
            at org.mygdx.gam.a.a(Unknown Source)
            at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "com.badlogic.gdx.graphics.g2d.BitmapFont" on path: DexPathList[[zip file "/data/app/org.mygdx.gam.android-1.apk"],nativeLibraryDirectories=[/data/app-lib/org.mygdx.gam.android-1, /vendor/lib, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:251)
            at java.lang.Class.forName(Class.java:216)
            at com.badlogic.gdx.utils.b.b.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.k.b(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.j.a(Unknown Source)
            at com.badlogic.gdx.utils.k.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.a(Unknown Source)
            at com.badlogic.gdx.e.a.a.i.<init>(Unknown Source)
            at org.mygdx.gam.a.a(Unknown Source)
            at com.badlogic.gdx.backends.android.i.onSurfaceChanged(Unknown Source)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)

这是我的 .json 文件。
{
com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: { file: default.fnt } },
com.badlogic.gdx.graphics.Color: {
    green: { a: 1, b: 0, g: 1, r: 0 },
    white: { a: 1, b: 1, g: 1, r: 1 },
    red: { a: 1, b: 0, g: 0, r: 1 },
    black: { a: 1, b: 0, g: 0, r: 0 },
},
com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: {
    dialogDim: { name: white, color: { r: 0, g: 0, b: 0, a: 0.45 } },
},
com.badlogic.gdx.scenes.scene2d.ui.Button$ButtonStyle: {
    default: { down: default-round-down, up: default-round },
    toggle: { down: default-round-down, checked: default-round-down, up: default-round }
},
com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: {
    default: { down: default-round-down, up: default-round, font: default-font, fontColor: white },
    toggle: { down: default-round-down, up: default-round, checked: default-round-down, font: default-font, fontColor: white, downFontColor: red }
},
com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: {
    default: { vScroll: default-scroll, hScrollKnob: default-round-large, background: default-rect, hScroll: default-scroll, vScrollKnob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: {
    default: {
        font: default-font, fontColor: white, background: default-select,
        scrollStyle: default,
        listStyle: { font: default-font, selection: default-select-selection }
    }
},
com.badlogic.gdx.scenes.scene2d.ui.SplitPane$SplitPaneStyle: {
    default-vertical: { handle: default-splitpane-vertical },
    default-horizontal: { handle: default-splitpane }
},
com.badlogic.gdx.scenes.scene2d.ui.Window$WindowStyle: {
    default: { titleFont: default-font, background: default-window, titleFontColor: white },
    dialog: { titleFont: default-font, background: default-window, titleFontColor: white, stageBackground: dialogDim }
},
com.badlogic.gdx.scenes.scene2d.ui.ProgressBar$ProgressBarStyle: {
    default-horizontal: { background: default-slider, knob: default-slider-knob },
    default-vertical: { background: default-slider, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle: {
    default-horizontal: { background: default-slider, knob: default-slider-knob },
    default-vertical: { background: default-slider, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: {
    default: { font: default-font, fontColor: white }
},
com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: {
    default: { selection: selection, background: textfield, font: default-font, fontColor: white, cursor: cursor }
},
com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle: {
    default: { checkboxOn: check-on, checkboxOff: check-off, font: default-font, fontColor: white }
},
com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: {
    default: { fontColorUnselected: white, selection: selection, fontColorSelected: white, font: default-font }
},
com.badlogic.gdx.scenes.scene2d.ui.Touchpad$TouchpadStyle: {
    default: { background: default-pane, knob: default-round-large }
},
com.badlogic.gdx.scenes.scene2d.ui.Tree$TreeStyle: {
    default: { minus: tree-minus, plus: tree-plus, selection: default-select-selection }
},
com.badlogic.gdx.scenes.scene2d.ui.TextTooltip$TextTooltipStyle: {
    default: {
        label: { font: default-font, fontColor: white },
        background: default-pane, wrapWidth: 150
    }
},
}

这些代码行很奇怪,如果我把它们去掉,程序就能正常运行,除了显然没有出现的按钮。

skin = new Skin(Gdx.files.internal("jsonSkin.json"));
TextButton btnStart = new TextButton("Start!!", skin);
btnStart.setPosition(50f,400f);
btnStart.setSize(260f,60f);
mainMenu.addActor(btnStart);

看起来你的Proguard配置没有排除libgdx类。由于Skin通过反射加载类,因此您不能允许Proguard更改这些类的名称。 - Tenfour04
你确定这个存在吗? skins/jsonSkin.json - Madmenyo
Menno Gouw -- 我可能在发布时更改了一些内容,但我可以保证我已经将 jsonSkin.json 放在 SKIN/ 文件夹和 assets 中。 - user5895975
_-Tenfour-_,您能告诉我如何不允许Proguard更改名称吗? - user5895975
我已禁用Proguard,但仍然出现错误,请有人能帮忙吗? - user5895975
4个回答

9

请将以下内容添加到您的配置文件中:

 -keep class com.badlogic.**{
   **[] $VALUES;
    *;
}

这将解决此问题以及反射问题。

编辑:

以上是禁用特定包中所有ProGuard功能的顶级规则。没有缩小,没有混淆;不针对类,也不针对成员。

Proguard会混淆我们在皮肤文件中使用的类,Skin通过反射加载类,因此我们必须不允许Proguard更改这些类的名称。

  1. 包中的双星号表示该顶级包下的每个包中的每个类;
  2. 花括号内的星号适用于这些类中的每个成员(变量、方法和常量)。

那么这行代码实际上是在做什么?我对Proguard非常陌生,这看起来像是一个几乎匹配所有东西的巨大通配符。在这种情况下,Proguard只有在混淆方面有用,而不是缩小文件大小。我+1,但如果您能详细说明一下就更好了。 - Madmenyo
1
@Madmenyo,我添加了更多细节。上面的规则禁用了libgdx包中的proguard,但是你自己的类仍然是安全的(混淆)。如果您更关心混淆,可以更深入地禁用com.badlogic.gdx.scenes.scene2d.ui上的混淆,并添加一些外部类,例如在皮肤文件中可能有的BitmapFontColor - Abhishek Aryan

3

问题是json序列化器需要确切的字段名来完成它的工作。

Abhishek正确,但我只需要忽略scene2d软件包的缩小,因此我将其放在proguard-rules.pro文件中。

 -keep class com.badlogic.gdx.scenes.scene2d.ui.**{
    **[] $VALUES;
     *;
 }

它将优化除皮肤加载器及其组件之外的所有其他代码。

如果您正在使用自己的类进行JSON序列化/反序列化,也需要添加类似的内容。

 -keep class com.your.game.data.**{
    **[] $VALUES;
     *;
 }

以下是关于在Android Studio中寻找proguard-rules.pro文件的截图,适用于初学者: enter image description here

0
把这个加入到你的proguard规则

-keep class com.badlogic.gdx.graphics.g2d.BitmapFont


0
在我的情况下,在build.gradle中,我为发布版本构建设置了以下配置:
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
      debuggable true
    }

但是我的proguard-rules.pro文件丢失了 - 现在默认的是proguard-project.txt。所以我将配置更改为:

  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
      debuggable true
    }

然后按照之前的答案应用正确的Proguard规则。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接