在从文件调用 Lua 脚本之前,在 Java 代码中设置 package.path。

我找到了在Android环境中使Lua脚本需要其他Lua脚本的方法。但是,这个解决方案将package.path配置放在顶级Lua脚本本身中。我想将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");

或者从load中获取LuaValue结果,然后将其传递给LuaClosure。它们都导致脚本在第一个require处失败,无法找到所引用的脚本。有人有任何想法吗?

*编辑- 如果有人知道如何将工作目录设置为/assets/lua/文件夹,以便我可以在Lua脚本中使用相对路径,那将是更可取的。

点赞
用户3770919
用户3770919

我以前认为自己尝试过,但是这是解决方案。

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 将如下所示:

require "test.luaFile"
2014-12-29 04:23:00
用户1994206
用户1994206

在 mnemy 的解决方案基础上,添加一些内容。

默认的 findResource 方法定义如下(PS:在 luaj 源代码的 BaseLib.java 中):

public InputStream findResource(String filename) {
    return getClass().getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
}

Android 的 getResourceAsStream 方法在相对于 Android 项目的根目录中搜索资源。(我用了链接 LuaJ and Android: cannot bind class,解决了一个类加载器的问题,Cloudy Zheng 的解决方案。) 所以,如果你想使用“require”来加载其他目录(例如“/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();
2016-09-12 12:56:51