Android Studio Lua环境配置
开发环境
1. Android Studio 3.5
2. java sdk: 1.8.0
3.android sdk:28
配置环境
添加lua支持语法支持插件,打开android studio -> File -> Settings
三方库选择
参考文章:https://gameinstitute.qq.com/community/detail/117865
Luaj 纯Java实现的Lua解析器,无需使用native
首先切换到Project目录,在gradle构建工具中添加依赖Luaj,然后同步
Java调用Lua函数
在main目录下新建assets资源目录文件夹,在其下存放lua文件
test.lua
luaV1 = "lua String"
function luaFun1()
print("Lua 无参无返回值方法");
end
function luaFun2(str)
return "来自Java的参数:"..str;
end
JavaTest.java
@Test
public void test1( ) {
Globals globals = JsePlatform.standardGlobals();
//加载Java脚本文件并编译Lua脚本
globals.loadfile("src/main/assets/test.lua").call();
//加载Lua常量
LuaValue luaStr = globals.get(LuaValue.valueOf("luaV1"));
System.out.println("来自Lua的字符串" + luaStr.toString());
//加载无参无返回值函数
LuaValue lua1 = globals.get(LuaValue.valueOf("luaFun1"));
lua1.call();
//加载有参有返回值函数
LuaValue lua2 = globals.get(LuaValue.valueOf("luaFun2"));
//传入参数
LuaValue str = lua2.call(LuaValue.valueOf("Java~"));
System.out.println(str.tostring());
}
运行测试方法test1输出
来自Lua的字符串lua String
Lua 无参无返回值方法
来自Java的参数:Java~
Lua调用Java
Utils.java
public void javaFun1(String str){
System.out.println("Java + " + str);
}
public static void javaStaticFun1(String str){
System.out.println("Static Java +" + str);
}
test.lua
function luaFun3()
--创建java对象
fun1 = luajava.newInstance("com.example.luaandroid.Utils");
fun1:javaFun1("Lua");
end
function luaFun4()
--绑定Java类
fun1 = luajava.bindClass("com.example.luaandroid.Utils");
fun1:javaStaticFun1("Lua");
end
JavaTest.java
@Test
public void test2(){
Globals globals = JsePlatform.standardGlobals();
//加载Java脚本文件并编译Lua脚本
globals.loadfile("src/main/assets/test.lua").call();
LuaValue lua1 = globals.get(LuaValue.valueOf("luaFun3"));
lua1.call();
}
运行测试方法test2输出:
Java + Lua
Static Java +Lua
Lua与Java运算速度对比
test.lua
function test()
a = 0;
for i = 0, 1000000, 1 do
a = a + i;
end
return "over";
end
JavaTest.java
@Test
public void test(){
long l = System.currentTimeMillis();
int a = 0;
for (int i = 0; i < 1000000; i++) {
a += i;
}
System.out.println("Java : "+ (System.currentTimeMillis() - l));
Globals globals = JsePlatform.standardGlobals();
//加载Java脚本文件并编译Lua脚本
globals.loadfile("src/main/assets/test.lua").call();
LuaValue lua1 = globals.get(LuaValue.valueOf("test"));
l = System.currentTimeMillis();
lua1.call().tostring();
System.out.println("Lua:"+ (System.currentTimeMillis() - l));
}
输出结果:
Java : 7
Lua:518
在不加Lua脚本加载的时间,多次测试,大概计算速度相差五十倍左右
LuaJava 这个没找到具体的库~~
Android-Lua GitHub地址:https://github.com/liangchenhe55/Android-Lua
引入库:
implementation group: 'com.blakequ.luajava', name: 'luajava', version: '1.0'
基本使用方法
Java调用Lua函数
MainActivity.java
//应用启动之后获取LuaState
mLuaState = LuaStateFactory.newLuaState();
mLuaState.openLibs();
//通过上下文返回lua脚本
mLuaState.LdoString(readAssetsTxt(this, "test.lua"));
//加载lua函数
mLuaState.getGlobal("luaFun1");
//传入参数
mLuaState.pushString("lua");
//第一个参数表示传入参数个数,第二个表示返回参数个数
mLuaState.call(1, 1);
//获取返回值
mLuaState.toString(-1);
test.lua
function luaFun1(str)
return str;
end
Lua中引用Java的方法
Java的方法需要是继承至JavaFunction()方法的,并重写构造函数和execute()以及register()方法
构造方法用于传入LuaState对象
execute()方法是想传入方法
register()为想生成的Lua函数取名
具体实现看后面的实例
Android中Lua应用
XMl文件配置
activity_main.xml
MyJavaFunction.java (注入Lua脚本中的方法一)
public class MyJavaFunction extends JavaFunction {
public MyJavaFunction(LuaState luaState) {
super(luaState);
}
@Override
public int execute() {
// 获取栈中Lua传入的参数,注意第一个参数固定为上下文环境。
String str = L.toString(2);
L.pushString("Java的数据 + Lua的Str:"+str);
return 1; // 返回值的个数
}
@Override
public void register(String name){
try {
// 注册为 Lua 全局函数
super.register("testJava");
} catch (Exception e) {
e.printStackTrace();
}
}
}
AsyncJavaFunction.java(注入Lua脚本中的Java方法二)
public class AsyncJavaFunction extends JavaFunction {
// lua 回调函数
// lua callback function
private LuaObject callbackFun;
public AsyncJavaFunction(LuaState L) {
super(L);
}
@Override
public int execute() {
// 获取Lua传入的参数,注意第一个参数固定为上下文环境。
if (L.isFunction(2)) {
callbackFun = L.getLuaObject(2);
new MyAsync().execute();
}
return 0;
}
void register() {
try {
// 注册为 Lua 全局函数
register("http");
} catch (LuaException e) {
e.printStackTrace();
}
}
class MyAsync extends AsyncTask{
long t;
@Override
protected void onPreExecute() {
super.onPreExecute();
t = System.currentTimeMillis();
}
@Override
protected Integer doInBackground(Integer... integers) {
try {
// 模拟耗时操作(例如网络请求)
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if (callbackFun != null) {
try {
// 2个参数,0 个返回值。
callbackFun.call(new Object[]{"OK", System.currentTimeMillis() - t}, 0);
} catch (LuaException e) {
e.printStackTrace();
}
}
}
}
}
test.lua
function luaFun1(str)
return testJava(str);
end
function luaCallback(tv)
-- http 函数是由 java `AsyncJavaFunction` 类注入的
-- http function was injected by java `AsyncJavaFunction`
http(function(result, time)
tv:setText(string.format("result: %s\ntime: %dms", result, time));
end
)
end
MainActivity.java (主程序文件)
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private LuaState mLuaState;
private Button mButton;
private Button mButton2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定控件
mTextView = findViewById(R.id.textView);
mButton = findViewById(R.id.button);
mButton2 = findViewById(R.id.button2);
//应用启动之后获取LuaState
mLuaState = LuaStateFactory.newLuaState();
mLuaState.openLibs();
//通过上下文返回lua脚本
mLuaState.LdoString(readAssetsTxt(this, "test.lua"));
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//利用Java函数生成lua函数,设置函数名为testJava
new MyJavaFunction(mLuaState).register("testJava");
//加载lua函数
mLuaState.getGlobal("luaFun1");
//传入参数
mLuaState.pushString("test");
//第一个参数表示传入参数个数,第二个表示返回参数个数
mLuaState.call(1, 1);
mTextView.setText(mLuaState.toString(-1));
}
});
mButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTextView.setText("Loading...");
new AsyncJavaFunction(mLuaState).register();
mLuaState.getGlobal("luaCallback");
mLuaState.pushJavaObject(mTextView);
mLuaState.call(1, 0);
}
});
}
public static String readAssetsTxt(Context context, String fileName) {
try {
InputStream is = context.getAssets().open(fileName);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String text = new String(buffer, "utf-8");
return text;
} catch (IOException e) {
e.printStackTrace();
}
return "err";
}
@Override
protected void onDestroy() {
//关闭lua栈
mLuaState.close();
super.onDestroy();
}
}