zoukankan      html  css  js  c++  java
  • cocos Lua与Java交互

    简介:

    cocos2d为了使Android SDK的接入,封装了LuaJavaBridge用于Java和Lua的相互调用。LuaJavaBridge从本质上来说,是通过C++作为中介,其调用流程为:

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

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

    lua调用java

    在cocos/cocos2d/luaj.lua文件下,lua调用java的方法接口:luaj.callStaticMethod

    local luaj = {}
    local callJavaStaticMethod = LuaJavaBridge.callStaticMethod
    
    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
    
    return luaj

    虽然在lua脚本中我们可能已添加了相关注释,但是还是再补充说明下:

    1. lua调用java的类方法,其中java方法一定要为static类型

    2. lua调用Java的方法一定要判定是否为Android平台,若在游戏中也要判定当前游戏的基础版本是否支持调用该SDK

    -- 判定是否为android平台
    -- 第一种方法
    local targetPlatform = cc.Application:getInstance():getTargetPlatform()
    if (cc.PLATFORM_OS_ANDROID == targetPlatform) then
        -- do something
    end 
    -- 第二种方法(推荐)
    if device.platform == "android" then
        -- do something
    end 

    3. 使用luaj.callStaticMethod时,注意第三个参数args一定要为table类型,否则将被转换{},导致错误

    4. 通过checkArguments的循环我们可以看到Java支持的几种lua参数或返回值类型简写如下:

    Lua类型 Lua简写 说明
    number F 浮点类型
    boolean Z 布尔类型
    function I 整数或Lua function
    string
    Ljava/lang/String;
    字符串
     
    V
    用于java方法中无返回值

    此处其实跟C++调用java时,设置其参数类型简写非常类似,但是lua没有C++那么多的数据类型支持,比如:char, shot, long, double等。

    5. 关于类型简写,格式为:(参数类型简写)返回类型简写

    我们简单的举一些例子,方便大家理解:

    lua调用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" 参数分别为字符串,整型,返回布尔类型

    6. 调用接口有两个返回值,假设以ok,result命名:

    若成功,ok为true, result若无返回值,则返回0,若有返回值,则返回;

    若失败,ok为false,result为错误代码,其对应的有:

    C++枚举类型 索引值 说明
    kLuaBridgeErrorOk 0 成功
    kLuaBridgeErrorInvalidParameters -1 无效的参数
    kLuaBridgeErrorClassNotFound -2 java类没找到
    kLuaBridgeErrorMethodNotFound -3 java类方法没找到
    kLuaBridgeErrorExceptionOccurred -4 方法执行时异常发生
    kLuaBridgeErrorMethodSignature -5 无效的类型简写
    kLuaBridgeErrorJavaVMError -6 Java 虚拟机错误

    拓展下,此处的返回错误码与关于lua与Object-C交互下的luaoc.callStaticMethod返回的错误码是一致的。

    接下来我们看下cocos2d-Lua的官方示例,并简单介绍Java调用Lua的相关接口:

    -- LuaBridgeTest.lua 示例仅摘抄了其主体代码
    function newLuaJavaBridge()
        local targetPlatform = cc.Application:getInstance():getTargetPlatform()
        if (cc.PLATFORM_OS_ANDROID ~= targetPlatform) then
            return 
        end 
            
        -- 用于Lua调用Java
        local luaj = require "cocos.cocos2d.luaj"                                   -- 引用库文件
        local className = "com/cocos2dx/sample/LuaJavaBridgeTest/LuaJavaBridgeTest" -- java类名
        local methodName = "addTwoNumbers"                                          -- java类方法名
        local args = {2 , 3}                                                        -- 参数
        local sigs = "(II)I"                                                        -- 类型简写
        local ok,ret  = luaj.callStaticMethod(className, methodName, args, sigs)
        if not ok then
            print("luaj error:", ret)
        else
            print("The ret is:", ret)
        end
    
        -- 用于Java调用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
    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);
        }
    }

    Java调用Lua

    在接入支付SDK的时候,其操作是异步的,在支付结束后后,Java需要通知Lua。因为若在Java调用Lua要添加引用:

    import org.cocos2dx.lib.Cocos2dxLuaJavaBridge;

    其主要接口有:

    // 调用局部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); 
  • 相关阅读:
    Web调用Linux客户端remmina运维
    前端和后端连载一起启动
    react redux 二次开发流程
    快上车,react 入门拾遗
    吐血整理!这篇带你彻底理解主存中存储单元地址的分配
    大学四年走来,这些网络工程师必备的模拟器我都给你整理好了
    主存、辅存、内存、外存、存储器是什么?还傻傻分不清楚?看完这一篇就够了
    一分钟理解系列—半导体存储芯片的知识点总结
    小白入门NAS—快速搭建私有云教程系列(一)
    五分钟理解主存储器的基本组成结构
  • 原文地址:https://www.cnblogs.com/SkyflyBird/p/11959531.html
Copyright © 2011-2022 走看看