我在網上看到了 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就沒事了。原因不明。