今天闲聊一些关于lua 与 native 之间相互调用的问题
lua 调用 oc 1.你一定知道我的使用场景是接入sdk对不对,嗯,大多数,我们需要使用ios设备系统提供的一些内容 很贴心,cocos提供了一个 luaBridge
lua部分代码
1 2 3 4 local luaBridge = require ("cocos/cocos2d/luaoc" )function luaoc.callStaticMethod (className, methodName, args)
函数返回值 当成功时,第一个值为 true,第二个值是 oc 方法的返回值(如果有)。 当失败时,第一个值为 false,第二个值是错误代码。
oc 部分代码 只是lua来调用oc部分
1 2 3 4 + (void )functionName:(NSDictionary *)dict{ NSLog (@"lua calling functionName" ); NSString *param = [dict valueForKey:@"paramName" ]; }
oc 部分代码 lua来调用oc部分并且需要回调部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + (void )functionName:(NSDictionary *)dict{ NSLog (@"lua calling functionName with callBack" ); int luaCallBackID = (int )[[dict valueForKey:@"callBack" ] integerValue]; } - (void )exeLuaCallback:(int )Handler callbackMsg:(NSString *)result { if (Handler){ cocos2d::LuaBridge::pushLuaFunctionById(Handler); cocos2d::LuaStack *stack = cocos2d::LuaBridge::getStack(); stack->pushString([result UTF8String]); stack->executeFunction(1 ); cocos2d::LuaBridge::releaseLuaFunctionById(luaCallBackID); } }
lua 和 java 的相互调用 同样很贴心,我们会发现 cocos 提供了 luaBridge
1 2 3 4 5 local callJavaStaticMethod = LuaJavaBridge.callStaticMethod// 类的名字 静态方法名字 参数 方法签名 function luaj.callStaticMethod (className, methodName, args, sig) //调用 Java 方法时,支持 int/float/boolean/String/Lua function 五种参数类型
函数返回值 当成功时,第一个值为 true,第二个值是 Java 方法的返回值(如果有)。 当失败时,第一个值为 false,第二个值是错误代码。
JNI Type Signatures : JNI Type Signatures
Java 部分代码
1 2 3 4 5 public static boolean isWXAppInstalled () { Log.v("AppActivity" , "isWXAppInstalled" ); return wxApi.isWXAppInstalled(); }
相对应 lua 部分
1 2 3 local luaBridge = require ("cocos/cocos2d/luaj" )local ok, ret = luaBridge.callStaticMethod("org/cocos2dx/lua/AppActivity" , "isWXAppInstalled" , nil , "()Z" )
lua 调用 java 并传递回调
java 代码部分
1 2 3 4 5 6 7 8 9 10 11 12 public static void registerGetAuthCodeHandler (int scriptHandler) { Log.v("BaseAppActivity" , "registerGetAuthCodeHandler" + scriptHandler); authCodeScriptHandler = scriptHandler; } Cocos2dxLuaJavaBridge.callLuaFunctionWithString(authCodeScriptHandler, authCode); Cocos2dxLuaJavaBridge.releaseLuaFunction(authCodeScriptHandler);
相对应 带有回调lua 部分
1 2 3 4 5 6 7 //传递callBack handler(self ,self .callFun) local luaBridge = require ("cocos/cocos2d/luaj" )luaBridge.callStaticMethod("org/cocos2dx/lua/AppActivity" , "sendAuthRequest" , nil , "()V" ) luaBridge.callStaticMethod("org/cocos2dx/lua/AppActivity" , "registerGetAuthCodeHandler" , {callback}, "(I)V" )
很完美?然而并没有结束!!!
cocos2d-x for Android 运行在多线程环境下,所以在 Lua 和 Java 交互时需要注意选择适当的线程。 cocos2d-x 在 Android 上以两个线程来运行,分别是负责图像渲染的 GL 线程和负责 Android 系统用户界面的 UI 线程。
在 cocos2d-x 启动后,Lua 代码将由 GL 线程调用,因此从 Lua 中调用的 Java 方法如果涉及到系统用户界面的显示、更新操作,那么就必须让这部分代码切换到 UI 线程上去运行。
反之亦然,从 Java 调用 Lua 代码时,需要让这个调用在 GL 线程上执行,否则 Lua 代码虽然执行了,但会无法更新 cocos2d-x 内部状态。
这才是要注意的坑!!!