版本: cocos2d-x

语言: C++/Java/Lua

简介

cocos2d-x原生平台Android 接入第三方SDK, 需要了解LuaJavaBridge的使用。

它封装了用于Java和Lua的相互调用, 其调用通过C++为中介,简要的流程:

Lua调用Java: Lua -> C++ -> Java

Java调用Lua: Java -> C++ -> Lua

以此方式来实现数据的交互, 接下来我们分别说下这两块东西。

Lua调用Java

lua的接口文件主要在 cocos/cocos2d目录下,主要的文件是:

luaj.lua Lua调用Android平台的接口文件luaoc.lua Lua调用苹果平台的接口文件

调用原生平台,使用的方法名均为: callStaticMethod

---------------- luaj.lua ----------------

-- 用于对参数转换为Java的类型简写

local function checkArguments(args, sig)

if type(args) ~= "table" then args = {} end

if sig then return args, sig end

-- Java支持Lua的几种参数类型number,boolean,string, function

-- 如果不存在,则按照如下程序进行转换

sig = {"("}

for i, v in ipairs(args) do

local t = type(v)

if t == "number" then

sig[#sig + 1] = "F"

elseif t == "boolean" then

sig[#sig + 1] = "Z"

elseif t == "function" then

sig[#sig + 1] = "I"

else

sig[#sig + 1] = "Ljava/lang/String;"

end

end

sig[#sig + 1] = ")V"

return args, table.concat(sig)

end

--[[

@function: 调用java的接口,注意在使用的时候一定要判定是否为为Android平台

@param: className Java完整的类名

@param: methodName Java类方法名

@param: args lua传入的参数,要为table类型,否则会被转换{}

@param: sig 类型简写名,格式为:(参数简写)返回类型简写

]]

function luaj.callStaticMethod(className, methodName, args, sig)

-- 检测参数args并将其转换为类型简写

local args, sig = checkArguments(args, sig)

return callJavaStaticMethod(className, methodName, args, sig)end

end

return luaj

使用Lua调用Java需要注意:

Java的方法一定要设置为static类型一定要判定平台的类型,比如Android,IOS,Mac等一定要根据考虑不同版本对原生平台方法的支持,这个主要是防止后续增加的功能,前期版本调用错误Lua的callStaticMethod 注意第三个传入参数,一定要为table表数据,避免错误

在Lua项目中,针对于平台的判定相关

-- 示例1

local targetPlatform = cc.Application:getInstance():getTargetPlatform()

if (cc.PLATFORM_OS_ANDROID == targetPlatform) then

-- do something

end

-- 示例2

if device.platform == "android" then

-- do something

end

checkArguments

它主要用于将Lua的参数转换为Java的类型简写,以用于获取数据,如下Java支持的Lua类型简写

Lua类型简写格式说明numberF浮点类型booleanZ布尔类型functionI整数或方法stringLjava/lang/String;字符串V用于java方法中无返回值

这个是跟C++调用Java是类似的,但Lua没有那么多的数据类型支持,比如C++中的char, shot, long, double等。

类型简写的格式大致为: (参数类型简写)返回类型简写,简单的实例:

Java方法简写说明void showText()“()V”无参数,无返回int getWifiLevel()“()I”无参数,返回整型String getSystemVersion()“()Ljava/lang/String;”无参数,返回字符串int addNumber(final int num1, final int num2)“(II)I”参数两个整型,返回整型boolean isGetPhoneData(final String name, final int Count)“(Ljava/lang/String;I)Z”参数分别为字符串,整型,返回布尔类型

在checkArguments中存在关于类型简写的转换,但是建议了解下,以备突发情况使用。

callStaticMethod

它是Lua调用调用C++的中介接口,用于将参数相关通过C++传递给Java。它的主要实现在:

// ../frameworks/cocos2d-x/cocos/scripting/lua-bindings/manual/platform/android目录下

// CCLuaJavaBridge.cpp

void LuaJavaBridge::luaopen_luaj(lua_State *L)

{

s_luaState = L;

lua_newtable(L);

lua_pushstring(L, "callStaticMethod");

lua_pushcfunction(L, LuaJavaBridge::callJavaStaticMethod);

lua_rawset(L, -3);

lua_setglobal(L, "LuaJavaBridge");

}

该接口在Lua中调用后主要会有两个返回值,分别是:

成功标记,布尔类型;错误编码,整数类型

如果成功,则错误编码为0,否则就是其他数值,主要的错误码有:

// CCLuaBridget.h

typedef enum {

// 成功

kLuaBridgeErrorOk = 0,

// 无效的参数

kLuaBridgeErrorInvalidParameters = -1,

// 类没有找到

kLuaBridgeErrorClassNotFound = -2,

// 方法没有找到

kLuaBridgeErrorMethodNotFound = -3,

// 执行异常

kLuaBridgeErrorExceptionOccurred = -4,

// 错误的类型简写

kLuaBridgeErrorMethodSignature = -5,

// 虚拟机错误

kLuaBridgeErrorJavaVMError = -6,

} LuaBridgeError;

这个错误类型与luaoc.lua的检测类型参数是相似的。官方实例:

Lua相关

-- LuaBridgeTest.lua 示例仅摘抄了其主体代码

function newLuaJavaBridge()

local targetPlatform = cc.Application:getInstance():getTargetPlatform()

if (cc.PLATFORM_OS_ANDROID ~= targetPlatform) then

return

end

-- 引用库文件

local luaj = require "cocos.cocos2d.luaj"

-- Java类名

local className = "com/cocos2dx/sample/LuaJavaBridgeTest/LuaJavaBridgeTest"

-- Java方法名

local methodName = "addTwoNumbers"

-- 参数

local args = {2, 3}

-- 类型简写

local sigs = "(II)I"

-- 调用方式一: 传入两个参数获取数值

local success, result = luaj.callStaticMethod(className, methodName, args, sigs)

if not success then

print("luaj error:", result)

else

print("The result is:", result)

end

-- 调用方式二: 传入两个参数获取结果通过Lua的回调显示日志

local function callbackLua(param)

if "success" == param then

print("java call back success")

end

end

args = { "callbacklua", callbackLua }

sigs = "(Ljava/lang/String;I)V"

ok = luaj.callStaticMethod(className,"callbackLua",args,sigs)

if not ok then

print("call callback error")

end

end

Java相关

package com.cocos2dx.sample.LuaJavaBridgeTest;

// 用于java调用Lua

import org.cocos2dx.lib.Cocos2dxLuaJavaBridge;

public class LuaJavaBridgeTest

{

// Lua调用java

public static int addTwoNumbers(final int num1,final int num2){

return num1 + num2;

}

// Java调用Lua

public static void callbackLua(final String tipInfo,final int luaFunc){

// 调用局部Lua-Function,将luaFunc结果发送给Lua

Cocos2dxLuaJavaBridge.callLuaFunctionWithString(luaFunc, "success");

Cocos2dxLuaJavaBridge.releaseLuaFunction(luaFunc);

}

}

至此,Lua调用Java告一段落。

Java调用Lua

Java是允许调用Lua的,同Java调用C++一样。主要的接口是:

// 调用局部Lua-Function

public static native int callLuaFunctionWithString(int luaFunctionId, String value);

// 调用全局Lua-Function

public static native int callLuaGlobalFunctionWithString(String luaFunctionName, String value);

// retain一次Lua-Function

public static native int retainLuaFunction(int luaFunctionId);

// release掉Lua-Function

public static native int releaseLuaFunction(int luaFunctionId);

后续补充…

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: