一、前言

接入Android SDK正式告一段落,在这段时间里面,依次接入了华为、应用宝、小米、360等等大大小小十来个SDK,也算对Unity接入渠道SDK有了较为全面的理解,对各个渠道的坑也算深有体会。。。。在接入过程中时间比较紧张,没办法抽空来进行总结深思。今天正好有空,便对之前的接入SDK的代码进行了一次重构,写了一个比较通用的Unity接入Android SDK的中间件,前人栽树,后人乘凉。

进入正题

如果有对一些只是有疑问的,可以看看我之前的三篇文章:

传送门:

Unity3d Android SDK接入解析(一)Unity3d 与 Android之间的互相调用:
http://blog.csdn.net/yang8456211/article/details/51331358

Unity3d Android SDK接入解析(二)Unity3d Android SDK的设计与两种接入方式
http://blog.csdn.net/yang8456211/article/details/51356193

Unity3d Android SDK接入解析(三)接入Android Library的理解(爱贝云支付为例)
http://blog.csdn.net/yang8456211/article/details/51435465

二、关于中间件的一些思考

2.1 为什么不用第三方平台

为什么要自己做一个Unity接入Android SDK的中间件呢?市面上例如Anysdk、易接这种第三方渠道是可以满足接入一次,生成大部分的SDK的,但是由于大渠道的审查越来越严格,已经禁止了这种第三方的平台SDK。因此,这些大渠道则必须由我们自己来接入了(不过二、三线渠道仍然是可以用第三方进行接入的),如果每个渠道都使用一个单独工程来管理,这无疑是一种非常浪费时间而且难以维护的事情,因此我想做的就是一个Unity的接入Android SDK的插件,所有的SDK的逻辑都封装好在Android层面,不同的游戏都可以按照相同的规则来接入进来,只需要调用通用的接口,准备好对应的资源即可。

2.2 怎么样做方便

我希望把这个中间件做的尽量能够通用,而且能够方便拆分、迭代。对Unity层面逻辑透明,只需要关注接口调用的时机和传入的参数。

  • 通用,形式简单

  • 只关注SDK业务逻辑

  • 调用简单

—— 通用,形式简单 ——

先说说通用吧:

对于Unity游戏来说,通常以Plugins的形式接入SDK比较方便,所以从这个思路出发,中间件的形式,我决定做成了jar包,而不是一个Library的工程,jar包里面只包含纯代码,没有资源和任何配置文件,调用方只用把jar包放在 Plugins/Android/libs 里面就可以使用了。对于不同游戏来说,没有差别。

最终的形式,就是一个uasdkinter的jar包,所有的SDK的逻辑会集成在这个jar里面。

形式简单的也有一层含义是,方便集成和拆分:

因此在package的设计上,每个渠道独立一个package放渠道代码,理论上我们导出jar包的时候,直接把所有渠道的代码都打进jar包就可以了,因为每次代码会根据传入的channel执行唯一的渠道,其他代码也就放在那了。

但是有些渠道会进行代码检测,例如360,会检测到包内含有小米支付相关的代码,审核不过,对应我们只需要在打jar的时候,勾选去掉对应的package就可以了。(因为是重构的代码框架,并没有包含很多sdk)

—— 只关注SDK业务逻辑 ——

中间件本身,只包含设计思想和一个简洁的框架。在接入渠道SDK的时候,我们只需要把渠道的SDK代码以一定的规则加入到中间件中即可。

所以这个中间件必须要健壮,框架写好之后,再添加新的SDK代码必须比较方便,无需对框架做大的改动。

因此我使用接口来实现,每个渠道SDK有两个class,一个管理账号信息,一个管理支付信息,账号与支付分离。

账号接口:

public interface UAGameInterf {// 初始化public void init(JSONObject sJson);// 登录public void login(JSONObject sJson);// 登出public void logout();// 退出游戏public void exit();// 初始化参数检查public boolean initParams(JSONObject sJson);// 设置生命周期的函数public void lifeCycle(int status);// 存储用户信息public void upUserInfo(JSONObject sJson);
}

支付接口:

public interface UAPayInterf {// 支付public void pay();// 初始化参数public boolean initParams(JSONObject sJson);
}

在添加SDK的时候,只需要新建账号class和支付的class,分别实现对应的接口,而不用管外层是怎么调用的,消息是怎么返回Unity的,而只用具体的实现每个接口即可,做到只关注SDK的业务逻辑(具体接口的设计说明后面详叙)。

—— 调用简单 ——

调用上,C#初始化“包名+类名”的AndroidJavaClass对象,使用这个对象来调用对应功能,区别于新建一个Activity继承UnityPlayerActivity 的模式,这个方法避免了一系列的蛋疼的问题(例如中间件工程需要和游戏工程的包名一样)

C#的调用:

中间件工程的包名是: com.uainter.main
接口类名是:UAMain

因此可以在C#创建AndroidJavaClass对象:

AndroidJavaClass ajc_SDKCall ajc_SDKCall = new AndroidJavaClass("com.uainter.main.UAMain");

为了方便调用,把对外的接口都做成了静态方法,所以用CallStatic去调用,因为每个渠道需要的参数类型和参数个数不确定,因为把传入参数定义成了一个Json。

例如调用小米渠道的Init方法:
小米渠道需要3个参数:appid、appkey、islandscape(登录与支付横屏还是竖屏显示)

string json = "{'channel':'11','debugmode':1,'appid':'xxx','appkey':'xxx','islandscape':false}";
ajc_SDKCall.CallStatic("uaInit",json);

Login方法:

string json = "{}";
ajc_SDKCall.CallStatic("uaLogin",json);

对于每个可能会有参数传入的方法,都设置了一个json对象作为参数,例如login方法,在接入应用宝的时候,需要在json数据中传入一个platform来判断是登录微信还是QQ。

中间键暴露出的接口有以下几个:

2.3 一些特殊操作的思考与处理

Activity生命周期的处理

理论我希望做到不需要修改启动的Activity,所以Activity生命周期的处理,放在了C#去控制,Android提供接口public void lifeCycle(int status); 在这个接口里面处理渠道SDK需要做的生命周期操作。

例如华为:
(Android 代码)

    public void lifeCycle(int status) {if (getActivity() == null) {DybGSdkUtil.E("还未Init初始化,不执行生命周期操作 ");return;}switch (status) {case DybGSdkConstants.onStart:break;case DybGSdkConstants.onResume:BuoyOpenSDK.getIntance().showSmallWindow(getActivity());break;case DybGSdkConstants.onPause:          BuoyOpenSDK.getIntance().hideSmallWindow(getActivity());BuoyOpenSDK.getIntance().hideBigWindow(getActivity());break;case DybGSdkConstants.onStop:break;case DybGSdkConstants.onDestroy:OpenHwID.releaseResouce();BuoyOpenSDK.getIntance().destroy(getActivity());break;default:break;}}

(C#调用)

    void OnApplicationPause(bool isPause){if (isPause) {string json = "{'status':'3'}";ajc_SDKCall.CallStatic("uaLifeCycle",json);}}void OnApplicationFocus(bool isFocus){if (isFocus){if (ajc_SDKCall != null){string json = "{'status':'1'}";ajc_SDKCall.CallStatic("uaLifeCycle",json);json = "{'status':'2'}";ajc_SDKCall.CallStatic("uaLifeCycle",json);}}}void OnApplicationQuit(){string json = "{'status':'5'}";ajc_SDKCall.CallStatic("uaLifeCycle",json);}

(对应的status和生命周期)

    // Android Activity生命周期public static final int onStart = 1;public static final int onResume = 2;public static final int onPause = 3;public static final int onStop = 4;public static final int onDestroy = 5;public static final int onRestart = 6;

实在遇到需要Activity的地方怎么处理?

只有在接入应用宝的时候,遇到了需要接入Activity的两个方法onNewIntent和onActivityResult时,需要接受qq和微信的回调,这种情况我也没有想到什么好办法,只有创建一个Activity,然后实现这个两个方法,并修改这个Activity为AndroidManifest里面的启动Activity。

遇到需要自定application的情况呢?

跟Activity类似,这个时候我们新建一个Application即可。

大部分的SDK方法需要在UI线程中调用

这个之前有说过,在这里只是列出来不详述了:

例如登录:

    public static void uaLogin(String jsonString) {try {final JSONObject sJson = new JSONObject(jsonString);final UAGameInterf uaManager = getSdkObj(sChannel);activity.runOnUiThread(new Runnable() {@Overridepublic void run() {uaManager.login(sJson);}});} catch (JSONException e) {e.printStackTrace();}}

怎么发送消息回Unity

    // 发送消息回Unity3dpublic static void dybCallback(JSONObject rjson) {UnityPlayer.UnitySendMessage(UAMain.callBackobj, UAMain.callBackFun,rjson.toString());}

其中callBackobj 和 callBackFun,分别对应接收返回值的对象的名称和回调方法。(此处我是写死的常量,也可以通过在init中传入对应的key来动态的修改这两个值)

可以看到,返回的也是一个json,里面包括了一个“callbackType”的key用来判断是哪个接口回调的结果,例如Init回调:

            JSONObject jsonObj = new JSONObject();String code = "1";jsonObj.put("callbackType", "Init");jsonObj.put("code", code);UAMain.dybCallback(jsonObj);

三、中间件对外接口说明

  • uaInit
public static void uaInit(String jsonString)

主要用于各个渠道SDK的初始化,传入的json字符串中,必须包含的是,debugMode和channel这两个key,channel是用于区分目前调用的是哪个渠道,debugMode是用于区分调试模式还是正式模式(一般SDK都会有两种模式),这里的debugMode我也用来作为显示日志的开关。剩下的key就要根据不同SDK所需要的不同的参数来传入。

  • uaLogin
public static void uaLogin(String jsonString)

一般SDK不用传入jsonString,直接传一个空的json字符串“{}”即可,当有些SDK需要在Login功能中加上切换账号功能是,我会传一个type进来,用来判断此时的操作是登录还是切换账号。

  • uaLogout
public static void uaLogout()

用于账号的退出,这个接口不需要参数。

  • uaExit
public static void uaExit()

用于退出游戏,一般SDK会有一个弹出框来显示一些论坛或者相关的广告信息,这个接口也不需要参数。

  • uaUpUserInfo
public static void uaUpUserInfo

用于信息的打点,就是报备一些信息,例如创建角色、角色升级、退出等等。

  • uaLifeCycle
public static void uaLifeCycle

用于生命周期函数的调用。

  • uaPay
public static void uaPay

用于支付。

四、后续思考

  • 最初写这个框架的时候,大概花费了2天的时间,后续接入中遇到了一些问题,也对这个中间件进行了一些修改,总的来说,能够满足基本上市面上大部分sdk的接入(至少我现在没有遇到接入不了的)。重构之后更加的简洁了,删掉了不少无用的东西。

  • 但是对于需要监听onNewIntent等函数的SDK,虽然可以处理(新建一个Activity去处理),却不太满意。在思考是否做成一个Activity形式的中间件更好(而不是一个Java的class),当然,还有生命周期上的处理,感觉很多东西都有优化的空间。

  • 花了整整一天写的东西,也希望“爬虫们”在转发的同时,也留个原文链接,因为不仅仅是我想把我拥有的知识去分享给他人,我也希望从他人的到宝贵的意见,指出我的错误和不足,这才是我写这篇文章的用意,是作为一个程序员最珍贵的东西,在此谢谢。

源码地址:
https://github.com/yang8456211/UASDKInter

如果还有不明白,可以到群里交流

unity3d-sdk交流Q群:113659593

杨光(atany)原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。
博文地址:http://blog.csdn.net/yang8456211/article/details/52231305
博客地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商业用途-保持一致”创作公用协议

Unity3d Android SDK接入解析(四)通用的Android SDK接入中间件相关推荐

  1. Android Volley完全解析(四),带你从源码的角度理解Volley

    经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了,但是对于Volley的工作原理,恐怕有很多朋友还不是很清楚.因此,本篇文章中我们就来一起阅读一下Volley的源码,将它的工作流程整体地 ...

  2. android用sax解析xml,详解android使用SAX解析XML文件

    解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析. DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了. 优点:整个 ...

  3. android webview 样式解析不正确,解决Android Webview加载Html富文本,h5字体样式不起作用问题...

    问题起因:WebView作为整个页面的一个部分展示,展示的是一段H5片段(Html中body标签中的部分) 问题描述:H5前端设置好的字体大小,在WebView中展示时不起作用,导致字体大小都一样 问 ...

  4. android 4.4 p600,四核MT6589+Android 4.1 TCL P600评测_中国经济网——国家经济门户

    内置不可拆卸电池 翻转至机身背部我们看到,TCLP600采用了仿拉丝面板设计,在手感上则略有些发滑.背部下方是针孔状的扬声器,800万像素的主摄像头和闪光灯一上一下排列.细心的朋友可能会留意到,主摄像 ...

  5. Android Volley完全解析3:定制自己的Request

    原文链接:http://blog.csdn.net/guolin_blog/article/details/17612763,CSDN 郭霖 经过前面两篇文章的学习,我们已经掌握了Volley各种Re ...

  6. Android art模式解析

    Android art模式解析 本文主要针对android系统art模式下面从安装apk到运行apk的一个过程,主要有一下几个方面: Art虚拟机介绍 安装时dex文件转化为oat文件 oat文件对应 ...

  7. Unity3d Android SDK接入解析(三)接入Android Library的理解(爱贝云支付为例)

    一.前言 写这个主题的原因,出于刚入门u3d,需要接入爱贝云支付的内容,苦于爱贝支付是一个Android的Library库,看到网上漫天遍野都是Android接入的帖子,但却没有我想要的关于Libra ...

  8. android 360游戏sdk,360ssp sdk接入说明 360移送媒体平台Android SDK 接入说明

    360ssp sdk接入说明 360移送媒体平台Android SDK 接入说明 360ssp sdk接入说明 360移送媒体平台Android SDK 接入说明: Android SDK SDK版本 ...

  9. Android Animation学习(四) ApiDemos解析:多属性动画

    Android Animation学习(四) ApiDemos解析:多属性动画 如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator , ( Animator可 ...

最新文章

  1. js表单验证,如果不为空时自动改变提交按钮的背景色
  2. 逻辑覆盖测试(一)语句覆盖
  3. java 邮件 内容_JAVA怎么获取邮件内容
  4. mongodb 事务_初探MongoDB事务机制
  5. SLF4j+LOG4j
  6. 我为什么更喜欢 Mac OS X
  7. java学习笔记1--开发环境平台总结
  8. mysql安装目录问题_Windows下MySQL的安装目录问题
  9. ASP.NET MVC 使用Log4Net在不同目录中记录不同类型的日志
  10. 谈谈Java虚拟机——Class文件结构
  11. 2020-08-27
  12. python实现一个简单的【图像中物体坐标】标注小工具
  13. 29 条运维工程师必会实用 Linux 命令
  14. 2022年更新正大杯获得国家二等奖经验优秀报告资料分享全国大学生市场调查与分析大赛市调大赛保研竞赛加分怎么找队友等全套经验分享
  15. 常见的几种手机传感器
  16. 去银行当程序员是一种什么体验
  17. TI DSP 28335 eCAP 测量脉冲占空比
  18. Android虚拟机的安装
  19. TEST语言编译器--语法分析
  20. 硬盘分区格式GPT与MBR无损互相转换而不破坏硬盘存储资料

热门文章

  1. PAT 1124 Raffle for Weibo Followers python解法
  2. 博客第二课-静态主页
  3. 基于 OAI 部署私有的 4G EPS
  4. 微信抢票——迭代周期一结束后感想
  5. 华农大学计算机专硕,华南农业大学电子工程学院(人工智能学院)林芳老师课题组招收计算机方向学硕及专硕...
  6. benj™ 100+城市街拍电影人像调色LR预设/移动LR预设/LUT预设效果预览
  7. 美团笔试(测试开发)
  8. 滴滴2018秋招编程题
  9. 高等数学:第十一章 无穷级数(1)常数项技术的概念、性质、审敛法、幂级数
  10. 带宽与速度的换算(表达式+例子)