LuaJavaBridge - lua与java互操作的简单解决方案
引入:Android平台代码和Lua代码的交互均通过C++和Java交互,Lua再和C++交互(lua <==> C++ <==> java)
我最开始遇见这种lua调用java的做法是先用 C/C++ 借助 JNI 编写调用 Java 的接口函数,然后再将这些函数通过 tolua++ 导出给 Lua 使用。这种做法最大的问题就是太繁琐,而且稍微有一点点修改,就要重新编译,严重降低了开发效率。
后来知道了luaj这个东西,发现之前的做法简直太傻帽了。
luaj 主要特征:
1、可以从lua调用Java Class Static Method
2、调用Java方法时,支持int/float/boolean/string/Lua function 五种参数类型
3、可以将Lua function作为参数传递给Java,并让Java保存Lua function的引用
4、可以从Java调用Lua的全局函数,或者调用引用指向的Lua fuction
GL线程和UI线程概念:
GL线程:负责图像渲染 (环境切换java->lua)
UI线程:负责Android系统的用户界面 (环境切换lua->java)
1、在 cocos2d-x 启动后,Lua 代码将由 GL 线程调用,因此从 Lua 中调用的 Java 方法如果涉及到系统用户界面的显示、更新操作,那么就必须让这部分代码切换到 UI 线程上去运行。
2、反之亦然,从 Java 调用 Lua 代码时,需要让这个调用在 GL 线程上执行,否则 Lua 代码虽然执行了,但会无法更新 cocos2d-x 内部状态。
lua中使用luaj.callStaticMethod来调用java静态方法:
//这里的func为回调函数
function JniUtil:callJavaCallbackLua(func) local luaj = require "cocos.cocos2d.luaj" local className = "org/cocos2dx/lua/AppActivity" local args = { "callbacklua", func } //参数 local sigs = "(Ljava/lang/String;I)V" //参数类型 local ok = luaj.callStaticMethod(className,"callbackLua",args,sigs) if not ok then print("============= call callback error") else print("------------- call callback success") end end
在AppActivity中,加入静态方法:
static int luaFuncCallback = 0; public static void callbackLua(final String tipInfo,final int luaFunc){ // 根据需要,看是否要retainLuaFunction luaFuncCallback = luaFunc; // tipInfo为Lua里传来的“callbacklua”这里没用 }
java调用lua方法:
public static native int callLuaFunctionWithString(int luaFunctionId, String value); // 调用局部Lua-Function public static native int callLuaGlobalFunctionWithString(String luaFunctionName, String value); // 调用全局Lua-Function public static native int retainLuaFunction(int luaFunctionId); // retain一次Lua-Function public static native int releaseLuaFunction(int luaFunctionId); // release掉Lua-Function
使用场景:例如我们在支付SDK中购买完了钻石回调到游戏中
java调用lua方法1:
sInstance.runOnGLThread(new Runnable() { @Override public void run() { Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFuncCallback, "success"); Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFuncCallback); } });
java调用lua方法2:
sInstance.runOnGLThread(new Runnable() { @Override public void run() { //G_CallbackFromJava为lua中的全局方法 Cocos2dxLuaJavaBridge.callLuaGlobalFunctionWithString("G_CallbackFromJava", "success"); } });