Android-Lua
Android-Lua copied to clipboard
请问应该怎么使用多线程呢?
我这样写,并没有用。。
public class FunctionThread extends JavaFunction {
/**
* Constructor that receives a LuaState.
*
* @param L LuaState object associated with this JavaFunction object
*/
private LuaObject luaFunc;
private LuaState luaThread;
public FunctionThread(LuaState L) {
super(L);
}
@Override
public int execute() throws LuaException {
if (L.isFunction(2)) {
luaFunc = L.getLuaObject(2);
luaThread= L.newThread();
luaThread.pushObjectValue(luaFunc);
new Thread(new Runnable() {
@Override
public void run() {
int p = luaThread.pcall(0,0,0);
if(p!=0){
Log.i("99999999999",luaThread.toString(-1));
}
}
}).start();
}
return 0;
}
public void register() {
try {
register("threads");
} catch (LuaException e) {
e.printStackTrace();
}
}
}
任何人都可以回答这个问题!
newThread()是luastate对象的一个方法,就是复制一份原有的luastate再添加到states列表上去。用了newThread()方法,感觉是有线程的感觉了(线程函数里面放一个死循环代码,然后点击按钮,可以正常触发按钮的点击事件,不用newThread()的话,UI线程会阻塞,按钮都点不。但是死循环里面的sleep()函数还是会阻塞UI线程,按钮按得快的话,app还会直接闪退)。我是用lua调用android的api做界面。
我没注意 LuaState 有这个方法。原则上来讲 Lua 不支持多线程。 所以我的方案上在 Java 里开启一个新线程,然后在这个线程中执行 Lua 函数。 可以把 Lua 函数作为参数传递给 Java,上面提到的代码已经写的很明白了。
我最开始就是你这个思路,实现的时候就有问题了。lua栈只有一个,如果java线程里面一直调用lua栈里面的一个函数,就会一直把函数和参数push到栈上。我按下按钮出发按钮点击事件的时候里面也是调用一个lua函数,这个函数和参数也会push到栈上,就和线程里面的冲突了,我估计是这样所以造成了app闪退
我大概了解了一下,LuaState 并不是线程安全的,所以我的方案有潜在风险。你的使用场景应该就触发了这种问题。
而你提到的 newThread
方法实际上是创建一个新的栈,如果把这个栈用于另一个线程,自然也就没了多线程共享栈导致的问题。但具体来讲还有许多工作要做,相关的函数包括 resume
, yield
, lock
, unlock
等。
我没研究过 lua 多线程的问题,目测也不属于此 lib 封装的问题。这个 issue 暂时保留以供讨论。
我测试了一下,newThread方法,返回的lua栈指针和原lua栈指针是一样的,也就是说newthread方法并不是深拷贝一份lua栈,所以我用了newthread还是会出现问题,用上线程锁可以解决这个问题,但是这个线程是个假的线程,因为用sleep()还是会阻塞UI线程。而且newthread方法只能用一次,用两次,也就是我想在开两个线程,app直接闪退。
还有lua函数和Java函数互相多层调用也有问题,比如:
--B开头的是Java封装的函数
--A开头的是lua函数
function A()
B(function()
B2()
end
)
end
A()
Java里面是用pcall或者call方法调用。 运行的结果就是logcat缓存爆表,app进程死掉。
B(function()
B2()
end
这样就没有问题。