我在网上看到了 LuaJavaBridge 的 使用方法这篇文章 https://segmentfault.com/a/1190000004252394?utm_source=tuicool&utm_medium=referral ,然后这里主要写一些笔记。

java调用lua或者lua调用java的方法都已经有一个现成的第三方java库提供了。而LuaJavaBridge 利用C++作为中介来实现整个过程,和那个第三方java库没关系。像这样:lua--C++--java ,java--C++--lua。

lua调用java的方法很简单

function JniUtil:callJavaBuyLife()
  local argsJson = nil
  local sigs = "()V"
  local luaj = require "cocos.cocos2d.luaj"
  local className = "org/cocos2dx/lua/AppActivity"
  local ok,ret = luaj.callStaticMethod(className, "pay", {argsJson}, sigs)
  if not ok then
    print("==== luaj error ==== : ", ret)
    return false
  else
    print("==== The JNI return is:", ret)
    return ret
  end
end

然后在java实现对应的pay函数

public static void pay() {
  // ...
}

这个过程和C++的 jni调用java很类似。

以下是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

分为全局函数和非全局函数,非全局函数可以retain和release,非全局函数要提供函数id

第一步,添加引用

import org.cocos2dx.lib.Cocos2dxLuaJavaBridge;

全局函数的调用很简单,值得注意的是,涉及OpenGL线程的要这样写

sInstance.runOnGLThread(new Runnable() {
  @Override
  public void run() {
    Cocos2dxLuaJavaBridge.callLuaGlobalFunctionWithString("G_CallbackFromJava", "success");
  }
});

其中 sInstance是对应的activity。lua函数要一个字符串参数。

第2种方法对应于lua的局部函数,其实所有非全局函数都是用这个。

那么,如何获取函数Id呢。。。

回忆一下刚才lua调用java,args = {"随便填一个字符串" , func} ,sigs = "(Ljava/lang/String;I)V" ,调用java函数的同时,将lua函数顺便传递进来了。然后就收到funcId了。

对应的java这样定义

static int luaFuncCallback = 0;
public static void callbackLua(final String tipInfo,final int luaFunc){
// 根据需要,看是否要retainLuaFunction
luaFuncCallback = luaFunc;
}

将 Lua function 作为参数传递给 Java 方法

很多时候,我们需要一种方法让 Java 代码可以向 Lua 代码传递一些消息。例如在大部分游戏平台的 SDK 中,涉及支付的部分都是异步操作的。在支付操作结束后,Java 代码需要通知 Lua 支付成功与否。

Lua 虚拟机中,Lua function 以值的形式保存。但这个值无法直接给 Java 用,所以 luaj 做了一个 Lua function 引用表。当一个 Lua function 传递给 Java 时,这个 function 对应的值会被存在引用表中,并获得一个唯一的引用 ID (整数)。Java 代码拿到这个引用 ID 后,就可以很方便的调用该 Lua function 了。

回顾最开始的示例代码,GameInterface_doBilling() 函数用于接收 Lua function 的参数就是 int 类型。因为实际传入 Java 函数的值是 Lua function 的引用 Id。(其实,Id并不一定要在这里传,随便找个地方传过来都可以,Id的值是一样的)

cocos2dx 2.1.5 的LuaJavaBridge的坑:

这个版本的 LuaJavaBridge 的全局调用函数并不是 CallLuaGlobalFunctionWithString ,而是分为两个CallLuaGlobalFunctionWithStringReturnInt和CallLuaGlobalFunctionWithStringReturnString。一开始我用CallLuaGlobalFunctionWithStringReturnString总是崩溃,然后换成CallLuaGlobalFunctionWithStringReturnInt就没事了。原因不明。

05-11 20:25