Cocos2d-x lua 集成芒果广告平台

用cocos2d-x lua开发完一个程序之后,要想在iOS端和Android端同时嵌入广告,是一件很麻烦的事情,如果还需要嵌入多家广告平台的SDK那就更蛋疼了,所以选择使用芒果广告平台来做广告集成,至于芒果广告平台是什么东东,还不了解的就自行百度谷歌吧,这里简单说就是一个广告平台的聚合平台,里面聚合了很多其他的广告平台,比如admob,百度,广点通。

芒果广告平台自己的SDK提供了各个版本的,包括Android原生和iOS原生,并且也提供了Cocos2d-x版本的demo和集成说明,但是我有一个感觉芒果广告平台提供的Cocos2d-x的集成说明有太多问题,也许对高手来说解决问题分分钟的事,但是对于我这种初学者来说,真是一步一个坑,照着说明文档走一遍,各种报错,各种崩溃。下面介绍一下集成的流程并且把这几天碰到的坑列一下,碰到坑的地方就用"坑x(x == index):"表示,其中芒果的后台配置各个广告平台的key和各种设置这里就不列了。

先说一下这个实现的原理,这个很重要,我要是最早能清楚原理,不至于掉那么多坑,原理是我们可以从芒果得到iOS的SDK和Android的SDK,把他们分别放到对应的程序结构下,做对应的配置之后,在当前平台是能正常运行的,但是因为我们是使用lua来开发程序的,所以涉及到要如何通过lua来调用到对应的iOS和Android的代码呢?
答案是:通过C++代码来做中间层,Android可以通过jni来和C++做交互,使用C++来封装一些调用Android SDK里面对应的展示广告的方法,iOS同理。这一层没问题之后,通过lua来调用C++的方法,从而实现在lua里调用方法让两个平台都兼容。

坑0:还没走就先掉到坑里面了,其实对开发过Cocos2d-x的人来说,这个不算事,但是因为我不知道原理,我开始看到他们官网提供的SDK下载里有cocos2d-x的,我挺开心的,因为之前只开发了iOS,在iOS里嵌入SDK是比较简单的,导入SDK,然后添加一些必要的framework,再配置一下对应的接口,基本就能通了。所以我之前认为既然提供了Cocos2d-x的SDK了,那基本也就和iOS导入差不多了吧,往项目里面导入SDK配置一下基本就完事了,没想到我错了,根本不是那么一回事呀。而且我后来才发现,官网上竟然提供了iOS版的Cocos2d-x SDK和Android版的Cocos2d-x SDK。
请输入图片描述
请输入图片描述

后来我研究了这两个SDK包,iOS的包里就是告诉开发者使用Cocos2d-x的项目怎么在ios平台下嵌入SDK,Android同理。并没有我之前想的那么简单。那就一个一个来吧,于是先按照说明文档开始嵌入Android部分

我上面提到过Cocos2d-x的集成文档问题很多,很多东西必须要用到的文档并没有提到,对于我这种新手来说,报个错就抓瞎了,都不知道从哪入手。

Android
按照步骤走
第一步导入各个集成各个广告平台的SDK,这些SDK其实就是jar包,按照说明导入,然后Add to Build Path就完事了,不过有的广告平台需要额外的一些jar包,比如广点通的就需要android-support-v4.jar,这个就需要开发者在嵌入什么广告平台的时候去对应的开发平台看一下嵌入需要的一些配置,做对应的处理。
第二步添加用户权限,在mainifest.xml里添加文档里说必须要添加的配置之后,根据每个广告平台的需要配置对应的内容

坑1:配置各个广告平台的时候最好下载一个它们官网的android完整demo,照那个里面的配,cocos2d-x版本的demo和说明文档都不全,我在这浪费了不少时间和他们的客服和技术沟通,还被因为是新手被鄙视问太基础的问题。

第三步在代码里添加调用的代码,这个没什么好说的,按照说明文档配置就行了,没有坑。这里的目的是在Android代码里配置了一些静态方法,等和C++交互调通了以后,让C++调用的。第四步,新建C++文件,MOGOAd.h和MOGOAd.cpp文件都是demo里提供的,把他们放在项项目目录下的/frameworks/runtime-src/Classes下就行了
.h文件的代码:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#include "cocos2d.h"
#endif
  using namespace cocos2d;
class MOGOAd
{
public:
MOGOAd();
virtual ~MOGOAd();
static void showBanner();
static void hideBanner();
};

.cpp的代码:

#include "MOGOAd.h"
MOGOAd::MOGOAd(){}
MOGOAd::~MOGOAd(){}
void MOGOAd::showBanner()
{
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 
        JniMethodInfo showBanner;
        bool isHave = JniHelper::getStaticMethodInfo(showBanner,"org/cocos2dx/cpp/AdsMogoCoCos2dx","showBannerStatic","()V");
        if (!isHave) {
            CCLog("jni:showBannerStatic false");
        }else{
            showBanner.env->CallStaticVoidMethod(showBanner.classID, showBanner.methodID);
        }
    #endif
}
void MOGOAd::hideBanner()
{
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 
        JniMethodInfo hideBanner;
        bool isHave = JniHelper::getStaticMethodInfo(hideBanner,"org/cocos2dx/cpp/AdsMogoCoCos2dx","hideBannerStatic","()V");
        if (!isHave) {
            CCLog("jni:hideBannerStatic false");
        }else{
            CCLog("jni:hideBannerStatic true");

            hideBanner.env->CallStaticVoidMethod(hideBanner.classID, hideBanner.methodID);
        }
  #endif
}

因为做测试的时候只用了banner样式的广告,所以我这里只提取了banner的两个方法,其他样式的根据自己的需求添加对应的方法就行了,这些C++的文件后面做兼容iOS的时候会修改里面的内容,后面再详细说,这里先用默认的。
第五步是配置jni,让C++通过jni和Android能交互,在Android的项目目录下有个jni文件夹,里面有Android.mk文件,这个是配置jni对交互的相关的,里面找到LOCAL _ SRC _ FILES参数(我这里的""之间加了空格的,因为编辑器会把两个""做转义,大加参照下面的代码):

//这里本来会有一堆系统默认添加的内容,我这里就列了最后几个
LOCAL_SRC_FILES := \
../../Classes/AppDelegate.cpp \
../../Classes/ConfigParser.cpp \
lua/Runtime_android.cpp \
lua/main.cpp
//---------------
//我们需要在lua/main.cpp的后面添加一个" \",然后再后面添加开始新加的MOGOAd.cpp文件的路径,改完后的样子:
LOCAL_SRC_FILES := \
../../Classes/AppDelegate.cpp \
../../Classes/ConfigParser.cpp \
lua/Runtime_android.cpp \
lua/main.cpp \
../../Classes/MOGOAd.cpp

添加完之后,他们完档上写了:
请输入图片描述
但是我的Cocos2d-x lua项目里,对应的目录下根本没有这个东西呀
请输入图片描述

但是这里的大概意思是明白的,就是虽然配置好了,所以这里需要编译一下,使用:

cocos compile -p android

不出意外是能编译通过的,但是编译之后只能说明Android到C++层面联通了,但是如何让Lua能和C++交互呢?参考我老大的博客Cocos2d-x下Lua调用自定义C++类和函数的最佳实践,我想我自己写还不如他写的1/10详细,我也是按照这篇文章一步一步调通的,文章比较长,如果只想调通程序,可以直接看里面的"第五层:使用cocos2d-x的方式来将C++类注册进Lua环境",其中里面列出的流程:"5、用Xcode将自定义的C++类和生成的桥接文件加入工程,不然编译不到"的解决方案是在Xcode里添加编译后的文件,但是Android下还需要单独配置一下:
在/项目根目录/frameworks/cocos2d-x/cocos/scripting/lua-bindings下有一个Android.mk,需要在里面的LOCAL _ SRC _ FILES里添加上:

auto/lua_MOGOAd_auto.cpp \

和上面添加LOCAL _SRC _ FILES类似,因为lua_MOGOAd_auto.cpp里面用到了MOGOAd.cpp,所以还需要在Android.mk里找到LOCAL _ C _ INCLUDES:在里面添加对应的Classes路径:

$(LOCAL_PATH)/../../../../runtime-src/Classes \

这一通处理完成之后,在编译一次:

cocos compile -p android

不出意外应该是能编译通过的,接下来直接通过Cocos Code IDE去跑编译之后的apk包就行了。显示效果:
请输入图片描述

iOS
第一步把下载的SDK导入到项目里,下载下来的SDK分成了三个文件夹AdsMoGoRes,AdsMoGOSDK,Utils,用Xcode打开Cocos2d-x的iOS_Mac项目,把这三个文件夹导入到项目的根目录下,其真实路径是/cocos2d-x项目根目录/frameworks/runtime-src/proj.ios_mac/

坑2:导入的时候需要注意一个问题,就是Cocos2d-x创建出来的项目默认是带了Mac版本的,而导入的SDK是给iOS用的,里面用到了的比如UIKit之类的framework在Mac下是没有的,所以在导入这些SDK文件选择Target的时候记得不要勾选Mac版本的Target,要不然后面编译Mac的时候各种报错各种找不到对应的framework,还得到Build Phases里的Compile Sources把添加进去的再挨个移除掉。

第二步添加各种必要的Framework,这个没什么好说的,添加就行了

坑3:这里再一次吐槽Cocos2d-x的说明文档写的烂,必须要的包都没有列全,EventkitUI.framework、GameController.framework都是必须要的,文档没列出来,只是把他们放在了建议添加的framework里

第三步更改静态库设置,点击程序Target文件,选择Build ?Settings标签页,找到Linking下面的Other ?Linker ?Flags,添加参 数-ObjC:
请输入图片描述

第四步添加各广告平台SDK,直接在官网下载芒果的iOS版的SDK,里面有很全的各个广告平台的SDK包,根据自己的需要导入到项目里就可以了,导入完之后最好去已经导入过的广告平台官网看一下,他们的SDK需要哪些framework支持,然后根据需求导入framework。

第五步配置MOGOAd.h和.cpp,如果集成Android的时候已经配置过lua调用C++的程序了,这里只需要修改MOGOAd.h和.cpp,使之能同时兼容iOS和Android就完成了,如果还没调通lua和C++的交互,请看上面介绍Android部分里的lua和C++交互部分。
MOGOAd.h:

#include "cocos2d.h"
//原来这里做的#include 都放到.cpp统一处理了
using namespace cocos2d;
class MOGOAd
{
    public:
    MOGOAd();
    virtual ~MOGOAd();
    static void showBanner();
    static void hideBanner();
};

MOGOAd.cpp:

#include "MOGOAd.h"
//如果是Android,就导入jni的一套东西,如果是iOS,就导入SDK里需要引入的头文件
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>

#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "AdsmogoBanner.h"
#include "AdsMogoInterstitial.h"
#endif

MOGOAd::MOGOAd(){}
MOGOAd::~MOGOAd(){}
void MOGOAd::showBanner()
{
//下面也是同样的操作,不同的平台不同的处理方式
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    JniMethodInfo showBanner;
    bool isHave = JniHelper::getStaticMethodInfo(showBanner,"org/cocos2dx/lua/AppActivity","showBannerStatic","()V");
    if (!isHave) {
        CCLog("jni:showBannerStatic false");

    }else{
        showBanner.env->CallStaticVoidMethod(showBanner.classID, showBanner.methodID);
    }

#elif (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
    char mogoid []="芒果的appid";

    AdsmogoBanner::sharedBanner()->showBanner(mogoid, AdsmogoBannerTypeNormalBanner, 0, 0, false);

#endif
}

void MOGOAd::hideBanner()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    JniMethodInfo hideBanner;
    bool isHave = JniHelper::getStaticMethodInfo(hideBanner,"org/cocos2dx/lua/AppActivity","hideBannerStatic","()V");
    if (!isHave) {
        CCLog("jni:hideBannerStatic false");

    }else{
        CCLog("jni:hideBannerStatic true");

        hideBanner.env->CallStaticVoidMethod(hideBanner.classID, hideBanner.methodID);
    }

#elif (CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
    AdsmogoBanner::sharedBanner()->hideBanner();
#endif
}

配置完成,执行:

cocos compile -p ios

不出意外,编译通过,然后在lua里调用:

-- 这里的ad指的是当时配置.ini文件时的target_namespace
ad.MOGOAd:showBanner()
ad.MOGOAd:hideBanner()

就能实现Banner的开启和关闭了,模拟器测试效果如下:
请输入图片描述

坑4:如果程序还在Mac上运行,这个时候如果编译Mac会报错,因为当时配置lua和C++交互的时候,在AppDelegate.cpp里添加过一段代码:

register_all_MOGOAd(stack->getLuaState())

而这个MOGOAd其实不应该加在Mac版本里的,有两种方法解决这个问题
第一种,添加这段代码的时候需要加一个判断:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID ||CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    register_all_MOGOAd(stack->getLuaState());
#endif

只有Android和iOS的情况下把这段代码添上就OK了,但是这样修改在lua层调用的时候不方便,需要判断一次设备才行,要不然lua会找不到对应的方法,应为Mac版本把那些方法都屏蔽了。
第二种,这里不改,修改Mac的Target,在Mac的Target里Build Phases里的Compile Sources里添加MOGOAd.cpp,添加之后:
请输入图片描述

然后点击项目下里的cocos2d _ lua _ bindings.xcodeproj,Target选择luabindings Mac,在后在Build Phases里的Compile Sources里添加lua _ MOGOAd _ auto.cpp,在Copy Headers里添加lua _ mogo _ auto.hpp,添加之后:
请输入图片描述
这种方法的目的就是把MOGOAd.cpp也放入到Mac的项目中,让其可以调用到,不至于在lua端报错,等于是把lua端的判断放到.cpp里做了,MOGOAd.cpp里面如果Mac什么都不做的话,什么都不写就行了。设置完成之后再编译运行,一切正常了,Mac下也能点对应的按钮,只是没有广告,效果图:
请输入图片描述

折腾了一个星期,总算搞定了。

添加一个新的问题,发现SDK里的ShowBanner是用来做初始化操作的,而hideBanner是直接对Banner的View做remove操作,并不是方法名所说的hide和show的关系,这样的设计的感受就是每次show都要等上一段时间,广告才能显示出来,已经反馈给对方的技术,会在下一个版本修复这个问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能组合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值