首页 > 技术文章 > LuaJavaBridge - lua与java互操作的简单解决方案

kane0526 2017-08-23 17:02 原文

引入: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");
    }
});

 

推荐阅读