我正在用Java开发使用Lua脚本的Android游戏。为了执行这些脚本,我将LuaJ与Java的ScriptEngine类一起使用。例如…
ScriptEngineManager sem = new ScriptEngineManager();
scriptEngine = sem.getEngineByExtension(".lua");
script = ((Compilable)scriptEngine).compile("some lua here");
但是,Android显然不支持此功能(这与android没有完整的JVM有关,我在某处读过)。有什么方法可以在Android上使用Lua脚本吗?也许有一个LuaJ替代方案?也许有一种直接使用LuaJ编译和执行Lua脚本的方法(尽管我看不到如何)。
仅供参考,当我尝试在Android上运行以下代码时,我看到此错误:
05-06 16:12:32.870: E/dalvikvm(17509): Could not find class 'javax.script.ScriptEngineManager', referenced from method unearth.levels.LevelReader.<init>
05-06 16:12:32.870: W/dalvikvm(17509): VFY: unable to resolve new-instance 787 (Ljavax/script/ScriptEngineManager;) in Lunearth/levels/LevelReader;
05-06 16:12:32.870: D/dalvikvm(17509): VFY: replacing opcode 0x22 at 0x0018
05-06 16:12:32.875: E/dalvikvm(17509): Could not find class 'javax.script.Compilable', referenced from method unearth.levels.LevelReader.parseScript
05-06 16:12:32.875: W/dalvikvm(17509): VFY: unable to resolve check-cast 782 (Ljavax/script/Compilable;) in Lunearth/levels/LevelReader;
05-06 16:12:32.875: D/dalvikvm(17509): VFY: replacing opcode 0x1f at 0x0047
05-06 16:12:32.875: W/dalvikvm(17509): VFY: unable to resolve exception class 788 (Ljavax/script/ScriptException;)
05-06 16:12:32.875: W/dalvikvm(17509): VFY: unable to find exception handler at addr 0x51
05-06 16:12:32.875: W/dalvikvm(17509): VFY: rejected Lunearth/levels/LevelReader;.parseScript (Lorg/w3c/dom/Element;Lunearth/levels/Level;)V
05-06 16:12:32.875: W/dalvikvm(17509): VFY: rejecting opcode 0x0d at 0x0051
05-06 16:12:32.875: W/dalvikvm(17509): VFY: rejected Lunearth/levels/LevelReader;.parseScript (Lorg/w3c/dom/Element;Lunearth/levels/Level;)V
05-06 16:12:32.875: W/dalvikvm(17509): Verifier rejected class Lunearth/levels/LevelReader;
05-06 16:12:32.890: W/dalvikvm(17509): threadid=11: thread exiting with uncaught exception (group=0x40c331f8)
05-06 16:12:32.895: E/AndroidRuntime(17509): FATAL EXCEPTION: GLThread 1062
05-06 16:12:32.895: E/AndroidRuntime(17509): java.lang.VerifyError: unearth/levels/LevelReader
05-06 16:12:32.895: E/AndroidRuntime(17509): at unearth.Game.startGame(Game.java:201)
05-06 16:12:32.895: E/AndroidRuntime(17509): at unearth.Game.update(Game.java:713)
05-06 16:12:32.895: E/AndroidRuntime(17509): at unearth.screens.LoadScreen.update(LoadScreen.java:56)
05-06 16:12:32.895: E/AndroidRuntime(17509): at unearth.UnearthListener.render(UnearthListener.java:71)
05-06 16:12:32.895: E/AndroidRuntime(17509): at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:423)
05-06 16:12:32.895: E/AndroidRuntime(17509): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
05-06 16:12:32.895: E/AndroidRuntime(17509): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1216)
05-06 16:12:58.600: D/dalvikvm(17509): GC_CONCURRENT freed 334K, 3% free 16196K/16647K, paused 2ms+6ms
也许这个项目有一些有用的代码?http://code.google.com/p/android-
scripting/
我找到了在Android上使用LuaJ的方法!:-)
关键是直接使用LuaJ
API,而不是通过javax.script
。由于没有教程,因此要弄清楚是有点棘手的,所以这里前后是这样,这样其他人就不必遍历LuaJ源代码和JavaDoc。我真的希望这能帮助某人,因为它驱使我疯狂!
注意: “ secretgame”不是我游戏的真实名称;-)
后:
package secretgame.scripting;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import org.luaj.vm2.lib.jse.JsePlatform;
import secretgame.SecretGameException;
import secretgame.events.EventArgs;
import secretgame.levels.Level;
public class DirectLuaj implements Lua
{
private final Level level;
private final ScriptTools scriptTools;
private final ScriptEvents scriptEvents;
private int nextId = 0;
private ArrayList<LuaClosure> scripts = new ArrayList<LuaClosure>();
public DirectLuaj(Level level, ScriptTools scriptTools,
ScriptEvents scriptEvents)
{
this.level = level;
this.scriptTools = scriptTools;
this.scriptEvents = scriptEvents;
}
@Override
public int add(String scriptText) throws SecretGameException
{
try {
InputStream input = new ByteArrayInputStream(scriptText.getBytes());
Prototype p = LuaC.compile(input, "script");
LuaValue g = JsePlatform.standardGlobals();
LuaClosure c = new LuaClosure(p, g);
scripts.add(c);
}
catch (IOException e) {
throw new SecretGameException("compile failed", e);
}
return nextId++;
}
@Override
public void run(int id, EventArgs args) throws SecretGameException
{
LuaClosure script = scripts.get(id);
LuaTable bindings = new LuaTable();
bindings.set("java", toLua(scriptTools));
bindings.set("level", toLua(level));
bindings.set("args", toLua(args));
bindings.set("events", toLua(scriptEvents));
script.setfenv(bindings);
script.call();
}
private LuaValue toLua(Object javaValue) {
return javaValue == null? LuaValue.NIL:
javaValue instanceof LuaValue? (LuaValue) javaValue:
CoerceJavaToLua.coerce(javaValue);
}
}
之前:
package secretgame.scripting;
import java.util.ArrayList;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import secretgame.SecretGameException;
import secretgame.events.EventArgs;
import secretgame.levels.Level;
// sadly this won't work on Android because there's no such thing
// as javax.script in Dalvik ... dumb Android java :|
public class JavaxScriptingLua implements Lua
{
private ScriptEngine scriptEngine;
private final Level level;
private final ScriptTools scriptTools;
private final ScriptEvents scriptEvents;
private int nextId = 0;
private ArrayList<CompiledScript> scripts = new ArrayList<CompiledScript>();
public JavaxScriptingLua(Level level, ScriptTools scriptTools, ScriptEvents scriptEvents)
{
this.level = level;
this.scriptTools = scriptTools;
this.scriptEvents = scriptEvents;
ScriptEngineManager sem = new ScriptEngineManager();
scriptEngine = sem.getEngineByExtension(".lua");
}
public int add(String scriptText) throws SecretGameException
{
try {
CompiledScript script = ((Compilable)scriptEngine).compile(scriptText);
scripts.add(script);
}
catch (ScriptException e) {
throw new SecretGameException("could not compile lua.", e);
}
return nextId++;
}
public void run(int id, EventArgs args) throws SecretGameException
{
Bindings bindings = scriptEngine.createBindings();
bindings.put("java", scriptTools);
bindings.put("level", level);
bindings.put("args", args);
bindings.put("events", scriptEvents);
try {
scripts.get(id).eval(bindings);
}
catch (ScriptException e) {
throw new SecretGameException("could not run script.", e);
}
}
}
我正在Android应用程序中创建一个项目。我已经在java eclipse环境中将java jdt ast作为独立应用程序实现了,并且我在控制台输出上得到了我需要的东西。现在我想把这个代码运行到我的Android应用程序项目中。但是,当我在文本中设置所有输出时,当我启动应用程序时,Android的视图,不幸的是它停止了,我不知道为什么...有人会知道为什么会发生这种情况吗?感谢您的帮助。 代码没
我用JDK 13制作了一个java应用程序。我用launch4j创建了一个exe文件。但是没有人可以运行它,因为每个人都有jre 1.8版本,而且它不会启动。。。我必须在安装中包含java jdk 13,并用它设置java_home?
问题内容: 我创建了新的libgdx项目,并且想在Android Studio中运行桌面应用程序。与运行配置有关吗?在Eclipse中,我可以选择“以Java应用程序运行”。 问题答案: 好吧,我做到了。这是解决方案https://github.com/libgdx/libgdx/wiki/Gradle-and-Intellij- IDEA#running-your-project ,单击加号()
问题内容: 我是一名Android开发人员,我想在我的应用程序中编写一条语句。在此语句中,我要检查默认浏览器(Android OS中 问题答案: 添加下面的Helper类: 现在,你可以从以下代码中检查所需的应用程序是否正在运行:
我使用JDK8制作了一个java应用程序,然后从JAR制作了一个可执行文件。 我已经使用launch4j从jar中创建了一个exe,并且没有可能选择Java11作为最新版本。 那么我怎样才能让这个exe在Java11上运行呢?
我有一个打包成WAR文件的Spring Boot web应用程序,我希望能够按需运行一些任务(脚本或命令)。例如: 初始化数据库模式 以编程方式为数据库设定种子 新版本应用程序(移动文件、数据库操作等)需要时进行数据迁移 验证存储文件和数据库内容之间的数据完整性 如果这些“命令”可以访问与Web应用程序本身相同的bean(服务,DAO)和模型,则实现起来会容易得多。我希望我必须在某个地方创建一个S