一、前言

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

进入正题

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

传送门:

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

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);

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

231

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

支付接口:

public interface UAPayInterf {

// 支付

public void pay();

// 初始化参数

public boolean initParams(JSONObject sJson);

}1

2

3

4

5

6

71

2

3

4

5

6

7

在添加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");11

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

例如调用小米渠道的Init方法:

小米渠道需要3个参数:appid、appkey、islandscape(登录与支付横屏还是竖屏显示)

string json = "{'channel':'11','debugmode':1,'appid':'xxx','appkey':'xxx','islandscape':false}";

ajc_SDKCall.CallStatic("uaInit",json);1

21

2

Login方法:

string json = "{}";

ajc_SDKCall.CallStatic("uaLogin",json);1

21

2

对于每个可能会有参数传入的方法,都设置了一个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;

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

261

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

(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);

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

261

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

(对应的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;1

2

3

4

5

6

71

2

3

4

5

6

7

实在遇到需要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() {

@Override

public void run() {

uaManager.login(sJson);

}

});

} catch (JSONException e) {

e.printStackTrace();

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

171

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

怎么发送消息回Unity

// 发送消息回Unity3d

public static void dybCallback(JSONObject rjson) {

UnityPlayer.UnitySendMessage(UAMain.callBackobj, UAMain.callBackFun,

rjson.toString());

}1

2

3

4

5

61

2

3

4

5

6

其中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);1

2

3

4

51

2

3

4

5

三、中间件对外接口说明

uaInit

public static void uaInit(String jsonString)11

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

uaLogin

public static void uaLogin(String jsonString)11

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

uaLogout

public static void uaLogout()11

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

uaExit

public static void uaExit()11

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

uaUpUserInfo

public static void uaUpUserInfo11

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

uaLifeCycle

public static void uaLifeCycle11

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

uaPay

public static void uaPay11

用于支付。

四、后续思考

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

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

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

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

unity3d-sdk交流Q群:113659593

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

  1. android应用程序架构由哪四个组成,android 应用程序结构是哪些

    src 目录 是源代码目录, 所有允许用户修改的 java 文件和用户自己添加的 java 文件都保存在这个目录中 是 1.5 版本新增的目录,用来保存 ADT 自动生成的 java 文件,例如 R. ...

  2. Android开发--使用实体类解析JSON文本

    Android开发–使用实体类解析JSON文本 在Android开发过程中,涉及到了API的调用的时候,会返回特定的数据,两个主流返回的数据格式是JSON形式和XML形式.但是相对于XML,JSON数 ...

  3. Unity3d Android SDK接入解析(四)通用的Android SDK接入中间件

    一.前言 接入Android SDK正式告一段落,在这段时间里面,依次接入了华为.应用宝.小米.360等等大大小小十来个SDK,也算对Unity接入渠道SDK有了较为全面的理解,对各个渠道的坑也算深有 ...

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

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

  5. 《ArcGIS Runtime SDK for Android开发笔记》——(6)、基于Android Studio的ArcGIS Android工程结构解析...

    1.前言 Android Studio 是第一个Google官方的 Android 开发环境.其他工具,例如 Eclipse,在 Android Studio 发布之前已经有了大规模的使用.为了帮助开 ...

  6. 接入腾讯广告联盟 Android SDK时遇到的坑

    出现的bug是:按照流程一步步接入腾讯广告SDK后,也按照注意事项对targetSDKVersion >= 24时的文件访问兼容性做了处理!但是8.0以上的手机仍然会出现当点击下载类广告的时候, ...

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

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

  8. Android接入高德地图SDK,Android高德SDK 地图篇一:集成高德SDK

    Android高德SDK 地图篇一:集成高德SDK 大家好,这是系列博文的第一篇: 系列博文会完成以下功能 一. 地图篇:利用高德SDK实现滴滴出行的效 二. 导航篇:利用高德SDK实现滴滴司机端的效 ...

  9. 喜马拉雅android sdk接入,喜马拉雅(com.ximalaya.ting.android) - 8.0.1.3 - 应用 - 酷安

    权限信息 · 在其他应用之上显示内容 · com.xiaomi.permission.AUTH_SERVICE · 完全的网络访问权限 · 查看WLAN连接 · 查看网络连接 · 读取手机状态和身份 ...

  10. Unity同时接入ShareSdk和微派支付sdk(二)

    说明一下,我是首先接入了微派支付的sdk,在微派AndroidManifest.xml的基础上加入的sharesdk.本人仅仅接入sharesdk和微派sdk,其他sdk可能不能这么做,慎重! 在任意 ...

最新文章

  1. pdf转ppt怎么转换,pdf转换ppt的方法分享
  2. python functools.reduce_Python-functools模块(reduce、partial、lru_cache)
  3. 剑破冰山—Oracle开发艺术 前言
  4. EntityFramework 7 OrderBy Skip Take-计算排序分页 SQL 翻译
  5. centos7 php多版本切换_centos7安装python3
  6. 四十九、IQ 与测试评分案例
  7. 机器学习篇-指标:AUC
  8. WebAPI(part9)--下拉菜单及留言案例
  9. 学习nginx 下面只是简单的配置文件
  10. Labview-隧道 移位寄存器
  11. bzoj 2257[Jsoi2009]瓶子和燃料 数论/裴蜀定理
  12. rust能捏人不_吃鸡:捏脸系统上线后,玩家们都嗨了
  13. unix network programming volume1 sorce code build and get(UNIX網絡編程卷1第三版)
  14. 微信小程序名称、简称设置规范
  15. 从零搭建一辆ROS小车
  16. 使用PMOS管构建电源延时供电电路
  17. 计算机走技术路线发展,硬件测试工程师发展前景_计算机硬件测试工程师_硬件测试工程师职责...
  18. macbook 终端命令怎么使用_苹果MAC系统怎么使用ping命令打开终端?
  19. 【2022修复版】社群扫码进群活码引流完整运营源码/对接免签约支付接口/推广正常绑定下级/带视频搭建教程
  20. RHEL 7.8 64bit MYSQL linux-generic 8.0.20 初始化安装

热门文章

  1. Java字符和数字列对齐_字符串(包含中英文、数字、符号)的对齐
  2. matlab实例一之Forward Collision Warning Using Sensor Fusion (视觉和毫米波雷达)
  3. 如何卸载vivo手机自带的应用程序(尤其是开启开发者选项后出现在状态栏的黄色警告)
  4. gnuplot详细操作
  5. 1078 字母三角形
  6. 微信小程序/小游戏运行环境小结
  7. MacBook 更新Big Sur后,虚拟机无法运行时显示该主机 CPU 类型不支持虚拟化性能计数器,模块“VPMC”启动失败,未能启动虚拟机
  8. 工欲善其事,必先利其器-IntelliJ IDEA
  9. python操作浏览器滚动条_python selenium webdriver处理浏览器滚动条
  10. php date 格式时分秒,PHP 把秒数转为时分秒格式