因此,在使用本教程设置后,我使用Scala在IntelliJ v12.1.6中开发了一个LibGDX项目:http://www.gamefromscratch.com/post/2013/12/01/Using-LibGDX-with-IntelliJ-with-Gradle.aspx。但是我注意到,在我的Android设备上测试游戏时,我收到以下错误
12-04 17:46:22.483: ERROR/AndroidRuntime(18951): FATAL EXCEPTION: GLThread 475
Process: com.voliant.rsoss, PID: 18951
java.lang.NoClassDefFoundError: scala.Predef$
at com.voliant.rsoss.Actors.Player.act(Player.scala:20)
at com.badlogic.gdx.scenes.scene2d.Group.act(Group.java:48)
at com.badlogic.gdx.scenes.scene2d.Stage.act(Stage.java:225)
at com.badlogic.gdx.scenes.scene2d.Stage.act(Stage.java:189)
at com.voliant.rsoss.Screens.GameScreen.render(GameScreen.scala:46)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:499)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1523)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
每当我尝试使用Scala原生的方法时(例如标准的println()方法)。
我怀疑android类找不到Scala使用的类,所以我试图用Scala库导出android项目。每当我尝试这个时,我得到一个错误,我有太多的方法,(similar to this)这是有道理的,因为Scala在项目中引入了足够多的方法来保证这个错误。
我的问题是如何让android项目知道Scala类和方法,以便我可以在android项目中有效地使用它们,就像我在桌面项目中一样?
谢谢!
答案 0 :(得分:5)
好吧,看来我已经能够解决我的问题了。
我能够使用ProGuard来减少我的项目所使用的方法,而Scala现在正如预期的那样在android上运行。我实际上遇到了一些与LibGDX本身有关的障碍,但设法弄清楚如何将它添加到配置中。 (with a little help from google of course)
对于遇到同样问题的其他人,这里是我的ProGuard cfg以及我用来帮助提出解决方案的链接。快乐的编码!
https://github.com/yareally/android-scala-intellij-no-sbt-plugin
-dontwarn scala.**
-dontwarn java.awt.**
-dontnote java.awt.**
-dontwarn com.badlogic.gdx.jnigen.**
-dontwarn com.badlogic.gdx.backends.android.AndroidDaydream
-dontwarn com.badlogic.gdx.backends.android.AndroidInputThreePlus
-dontwarn com.badlogic.gdx.backends.android.AndroidGraphicsDaydream
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
-keep class * implements org.xml.sax.EntityResolver
-keepclassmembers class * {
** MODULE$;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool {
long eventCount;
int workerCounts;
int runControl;
scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
int base;
int sp;
int runState;
}
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
int status;
}
-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue {
scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head;
scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail;
scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
}
-keep class com.badlogic.gdx.backends.android.AndroidInput {
public protected private *;
}
-keep class com.badlogic.gdx.backends.android.AndroidInputFactory {
public protected private *;
}
-keep class com.badlogic.gdx.backends.android.AndroidInputThreePlus {
public protected private *;
}
-keep class com.badlogic.gdx.backends.android.AndroidApplicationConfiguration {
public protected private *;
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}