我想出了如何在Android环境中使Lua脚本需要其他Lua脚本。
但是,该解决方案在顶级Lua脚本本身中具有package.path配置。我想将 package.path 配置移动到运行脚本的 Java 代码中,因为 package.path 特定于 Android 环境,而脚本可以在任何地方运行。
这是我尝试过的:
InputStream input getAssets().open("lua/test/pathTest.lua");
Prototype prototype = LuaC.instance.compile(input, "pathTest.lua");
Globals globals = JsePlatform.standardGlobals();
globals.load(new BaseLib());
globals.load("package.path = package.path .. ';/assets/lua/?.lua;/assets/lua/test/?.lua'");
LuaClosure c = new LuaClosure(prototype, globals);
c.call();
我还尝试了其他一些形式,例如:
globals.load(new StringReader("package.path = package.path .. ";/assets/lua/?.lua;/assets/lua/test/?.lua""), "pathTest.lua");
或者从负载中获取LuaValue结果并将其传递给LuaClosure。它们都会导致脚本在第一require
失败,无法找到引用的脚本。
有人有什么想法吗?
*edit - 如果有人知道如何将工作目录设置为/assets/lua/文件夹,所以我可以在 Lua 脚本中使用那里的相对路径,那将是可取的。
以为我以前尝试过这个,但这是解决方案。
InputStream input getAssets().open("lua/test/pathTest.lua");
Prototype prototype = LuaC.instance.compile(input, "pathTest.lua");
Globals globals = JsePlatform.standardGlobals();
globals.load(new BaseLib());
globals.load(new StringReader("package.path = '/assets/lua/?.lua;'"), "initAndroidPath").call();
LuaClosure c = new LuaClosure(prototype, globals);
c.call();
这将初始化 Android 环境到 assets/lua/文件夹的路径。这允许我在 Lua 脚本的require
调用中使用相对路径。
例如,要求在子目录中有一个文件:assets/lua/test/luaScript.lua
Lua 要求如下所示:
require "test.luaFile"
在 mnemy 解决方案的基础上,添加一些内容。默认的findResource方法定义是(PS:在luaj源代码的BaseLib.java
):public InputStream findResource(String filename) {
return getClass().getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
}
Android 的 getResourceAsStream 方法相对于 android 项目的根目录搜索资源。(我用链接 LuaJ 和 Android 解决了类加载器问题:无法绑定类,Cloudy Zheng 的解决方案。所以,如果你想使用"requre"在其他目录中加载其他模块(例如"/storage/emulated/0/temp/test/lua"),你可以像这样实现自己的findResource接口:
// Implement a finder that loads from absolute path.
public InputStream findResource(String name) {
try {
File f = new File(name);
return new FileInputStream(f);
} catch (java.io.IOException ioe) {
return null;
}
}
并设置为您的globals.finder。然后相应地调整搜索路径:
globals.load(new StringReader("package.path = '/storage/emulated/0/temp/test/lua/?.lua;'"), "initAndroidPath").call();