一、简介

  通常一款游戏开发到后期,一般都会涉及到第三方SDK的接入与集成,对于不熟悉SDK接入的同学来说,接SDK每次都是云里雾里,而熟悉SDK接入的同学又觉得不断地重复做接入SDK工作这样没有成就感,太尼玛无聊了(Android渠道一弄就十几个,直接吐血)。其实通常情况下接入SDK都是很简单的一个过程,本系列博客就让马三和大家从小白开始,从零基础开始学习如何接入SDK以及一些常见的SDK的接入流程。本系列博客规划为以下几篇:

  • SDK接入与集成——小白入门篇(介绍环境搭建以及Unity和Android的基本交互与调用)

  • SDK接入与集成——信鸽SDK篇(介绍消息推送框架--信鸽SDK的接入)

  • SDK接入与集成——QQ与微信SDK篇(都是腾讯开放平台的,就放在一起学了)

  • SDK接入与集成——科大讯飞SDK篇(游戏中的语音通信和语音识别会用到此SDK)

  • SDK接入与集成——百度地图SDK篇(做LBS游戏必不可少)

  • SDK接入与集成——第三方SDK接入解决方案AnySDK篇

  • SDK接入与集成——构建自己的Android集成多SDK框架篇

  先挖了这么多坑,以后慢慢填吧,放心博主肯定不会太监的。

回到顶部

二、浅谈常用的两种接入方案

1.第三方SDK接入解决方案

  其实游戏SDK接入发展到现在,已经有很多成熟的第三方SDK接入解决方案了,比如AnySDK,ShareSDK,U8SDK等等。这些第三方SDK接入解决方案的整个接入过程,不改变任何SDK的功能、特性、参数等,对于最终玩家而言是完全透明无感知的。让CP商能有更多时间更专注于游戏本身的品质。第三方SDK包括了渠道SDK、用户系统、支付系统、广告系统、统计系统、分享系统等等。利用他们可以轻松快速接入第三方SDK。

  第三方SDK的统一验证流程基本如下:

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

2.手动接入SDK

  既然上面说的第三方解决方案那么好,为什么我们还有手动去接入SDK呢?造轮子就这么上瘾?其实接入了一些第三方的SDK解决方案以后,我们有的游戏数据是要经过他们的服务器的,对于一些游戏厂商来说,不想让自己的数据经过别人的服务器,或者需要对验证服务器有完全自主的控制权,那么必然要手动接入各种SDK了。另外还有一些奇奇怪怪,非常诡异的SDK,我们也是要手动去接入的,不能都指望第三方的集成。而且作为一名合格的猿类来收,知其然更要知其所以然,掌握SDK的接入原理和过程很有必要。

回到顶部

三、开始接入!Unity与Android的交互

  前面啰嗦了那麽多,到这里终于可以开始实战操作了。

1.Android开发环境搭建

  关于Android环境的搭建,网上已经有很多博客了,介绍的很详细,马三就不在这里水了。这里给大家安利一个关于Android开发工具的好网站:http://www.androiddevtools.cn/ 。上面提供了很多可用的AndroidADK国内镜像和教程。

2.Android端的开发工作

  (1)打开IDE建立一个空的Android库工程,这里我用Eclispe举例。注意Min Required SDK最好选择4.0以上,要不然还需要引入android-support-v7兼容包,比较麻烦,之后我们可以把这个Min Required SDK 再该回来的。需要注意的两步已经截图了,剩下一路Next操作即可。注意包名和勾选Mark this project as a library选项。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  (2)导入Classes.jar包到Android工程中

  Unity和Android做交互,他们两个之间不认识肯定,没法直接通信,因此需要一个中间的搭桥牵线的人,Classes.jar就起到了这个作用。Classes.jar是由Unity提供给我们的,我们需要找到它并且引入到我们的Android项目中。Claess.jar的路径一般如下 X盘:\xxx目录\Unity\Editor\Data\PlaybackEngines\androidplayer\release\bin\classes.jar(不同的计算机上,这个位置可能会有所不同,大家按照自己的路径添加即可)。我们找到它直接拖到我们的Android工程的libs目录下。然后在它上面右键,将其添加到Build Path中。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  添加到Build Path成功以后,工程是这个样子的。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  (3)编写Android端的代码

  我们在Android端编写一些代码,提供一些接口来供Unity一会的调用。打开我们的MainActivity.java,然后添加代码。需要注意的是,让我们的MainActivity继承Jar包中的UnityPlayerActivity类,这样,Unity才能调的到哦,缺什么包,直接让Eclipe自动导下包即可,快捷键ctrl+shift+o。对了,还需要把 setContentView(R.layout.activity_main); 这段代码注释掉,要不然会显示Android的默认布局文件,上面就一个 Hello World。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 

  简单的写了几个普通方法和一个静态方法,供一会的测试调用。(无论是静态方法还是普通方法,在Unity中都是可以调用的到的)MainActicity.java的代码内容如下:

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1 package com.mx.sdkbase; 2  3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.Menu; 6 import android.view.MenuItem; 7 import android.widget.Toast; 8  9 import com.unity3d.player.UnityPlayer;10 import com.unity3d.player.UnityPlayerActivity;11 12 public class MainActivity extends UnityPlayerActivity {13 14     private static MainActivity instance;15 16     @Override17     protected void onCreate(Bundle savedInstanceState) {18         super.onCreate(savedInstanceState);19         // setContentView(R.layout.activity_main);20 21         instance = this;22     }23 24     @Override25     public boolean onCreateOptionsMenu(Menu menu) {26         // Inflate the menu; this adds items to the action bar if it is present.27         getMenuInflater().inflate(R.menu.main, menu);28         return true;29     }30 31     @Override32     public boolean onOptionsItemSelected(MenuItem item) {33         // Handle action bar item clicks here. The action bar will34         // automatically handle clicks on the Home/Up button, so long35         // as you specify a parent activity in AndroidManifest.xml.36         int id = item.getItemId();37         if (id == R.id.action_settings) {38             return true;39         }40         return super.onOptionsItemSelected(item);41     }42 43     44     /**45      * 供Unity调用的求和函数46      * @param x47      * @param y48      * @return49      */50     public int Sum(int x, int y) {51         return x + y;52     }53 54     /**供Unity调用的比较最大值函数55      * @param x56      * @param y57      * @return58      */59     public int Max(int x, int y) {60         return Math.max(x, y);61     }62 63     64     /**供Unity调用的显示吐司的函数65      * @param str66      */67     public void MakeToast(String str) {68         Toast.makeText(this, str, Toast.LENGTH_LONG).show();69     }70 71     72     /**供Unity调用的自加一函数73      * @param x74      * @return75      */76     public int AddOne(int x) {77         return x + 1;78     }79 80     81     /**供Unity调用的静态方法,单例类,返回当前的Activity对象82      * @return83      */84     public static MainActivity GetInstance() {85         return instance;86     }87     88     89     /**供Unity调用的函数,此函数会回调指定的一个Unity中的方法,完成数据的双向交互90      * @param str91      */92     public void CallUnityFunc(String str){93         str=str+"Android Call Unity.";94         String ReceiveObject="MessageHandler";95         String ReceiverMethod="Receive";96         UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);97     }98 }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 

   (4)导出我们的Android项目为Jar包供Unity调用

  在我们的项目上面右键,然后选择Export,选择Java目录下的 Jar file。因为没有用到第三方的jar包或者lib库,因此只要勾选src/和res/目录导出为jar包即可。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  (5)Unity端工程的开发

  建立一个新的空Unity工程,然后在Asset/目录下建立如下路径的文件夹:Plugins/Android。从名字就可以看出来,这个文件夹是用来存放安卓的插件的。然后将我们上面刚刚导出的SDKBase.jar 包导入到这个目录下,并且将Andoird工程目录下的,libs/ 、res/ 、AndroidMainFest.xml 都复制到该路径下。

  需要特别注意的是要将Unity 项目中 libs下的classes.jar文件删除掉,这个就是上面提到的那个起到中介作用的jar包,一定要删掉!一定要删掉!一定要删掉!(重要的事情说三遍,网上不少教程都是针对Unity老版的教程,没有提到要删除这个classes.jar包,结果在Unity 5.x中打包肯定会出错)。出错截图如下所示。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训 移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  然后我们建立一个场景,简单地在里面放上一些Label和输入框、按钮,供我们验证交互操作。并且编写一个脚本(MessageHandler.cs即是我创建的脚本), 在其中编写用来调用Jar包的C#方法,然后将按钮和这些函数绑定(Unity基本操作,不赘述了)。

  移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训 移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  MessageHandler.cs 脚本的内容如下,函数的功能看注释就行了,写得很全。

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 1 using System; 2 using UnityEngine; 3 using UnityEngine.UI; 4  5 public class MessageHandler : MonoBehaviour 6 { 7     private AndroidJavaClass _jc; 8     private AndroidJavaObject _jo; 9 10     public InputField inputFieldA;11     public InputField inputFiledB;12     public Text resultLabel;13 14     // Use this for initialization15     void Start()16     {17         //初始化18         //"com.unity3d.player.UnityPlayer"和"currentActivity"这两个参数都是固定的19         //UnityPlayerActivity里面对其进行了处理20         _jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");21         _jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");22     }23 24     public void AddOne()25     {26         int a = Convert.ToInt32(inputFieldA.text);27 28         //注意,这里使用的就不是之前默认的com.unity3d.player.UnityPlayer,而是需要传入自己的类(实现了需要调用相应方法的类)29         //因为默认的UnityPlayer中是没有我们所需要的方法的,所以需要加载自己的类30         AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");31         //调用Java中的静态方法,单例模式,返回当前Activity实例32         AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");33         resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);34     }35 36     public void Sum()37     {38         int a = Convert.ToInt32(inputFieldA.text);39         int b = Convert.ToInt32(inputFiledB.text);40         //调用Java类中的普通方法,返回值为int型41         resultLabel.text = "Sum: " + _jo.Call<int>("Sum", a, b);42     }43 44     public void Max()45     {46         int a = Convert.ToInt32(inputFieldA.text);47         int b = Convert.ToInt32(inputFiledB.text);48         resultLabel.text = "Max: " + _jo.Call<int>("Max", a, b);49     }50 51     public void CallUnityFunc()52     {53         //调用Java中的一个方法,该方法会回调Unity中的指定的一个方法,这里会回调Receive( )54         _jo.Call("CallUnityFunc","Unity Call Android.\n");55     }56 57     public void Receive(string str)58     {59         resultLabel.text = str;60     }61 62     public void Toast()63     {64         _jo.Call("MakeToast","Unity 调用Toast");65     }66 }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

 

  通过上面的代码,我们就可以看出来,想在Unity中调用Android的代码,主要涉及到了两个类。AndroidJavaClass 和 AndroidJavaObject 。这两个类在Unity API手册里面有详细的解释。

  下面的代码是获取到对应包名的java.lang.Class实例,这里获取到的是com.unity3d.player.UnityPlayer类。

_jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

  下面的代码是获取到UnityPlayer类中的静态字段,它的返回值类型是AndroidJavaObject对象。

_jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");

  通过以上两行代码,我们可以获取到这个AndroidJavaObject 对象,然后用 AndroidJavaObject 对象就可以任意地调用Android中的静态和非静态函数了。其中两个函数中的字符串参数 "com.unity3d.player.UnityPlayer" 和 "currentActivity" 都是固定的写法,我们不用去改变。

  AndroidJavaObject 类的一些常用方法及功能如下表所示:

AndroidJavaObject构造函数,根据类名返回AndroidJavaObject对象
Call调用Android代码中的非静态方法
CallStatic调用Android代码中的静态方法
DisposeIDisposable 回调
Get获取Android代码中的非静态字段
GetRawClass获取一个指向Java class的原始引用
GetRawObject获取一个指向Java object的原始引用
GetStatic获取Android代码中的静态字段
Set设置Android代码中的非静态字段
SetStatic设置Android代码中的静态字段

 

  另外,我们还有第二种方法去访问Java的代码,那就是利用我们之前在Java代码中写的 GetInstance() 静态方法,它会返回一个MainActivity的实例,我们拿到这个实例以后,就能访问里面的方法和字段了。需要注意的是此时的AndroidJavaClass构造函数中传递的字符串就不是 "com.unity3d.player.UnityPlayer" 了。而是要传入自己的包名,比如代码中的 “com.mx.sdkbase.MainActivity” 。代码如下:

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

        int a = Convert.ToInt32(inputFieldA.text);        //注意,这里使用的就不是之前默认的com.unity3d.player.UnityPlayer,而是需要传入自己的类(实现了需要调用相应方法的类)        //因为默认的UnityPlayer中是没有我们所需要的方法的,所以需要加载自己的类
        AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");        //调用Java中的静态方法,单例模式,返回当前Activity实例
        AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");
        resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  不止Unity可以调用Android的代码,Android也可以反过来回调Unity的代码。下面这段代码就是用来回调Unity函数的:

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

    /**供Unity调用的函数,此函数会回调指定的一个Unity中的方法,完成数据的双向交互
     * @param str     */
    public void CallUnityFunc(String str){
        str=str+"Android Call Unity.";
        String ReceiveObject="MessageHandler";
        String ReceiverMethod="Receive";
        UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
    }

移动开发培训,Android培训,安卓培训,手机开发培训,手机维修培训,手机软件培训

  利用UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str); 就可以返回过来回调一个Unity中的方法,完成Unity和Android的双向通信。其中第一个参数是接受该回调的gameobject名称,第二个参数是挂载在该gameobject上面的一个脚本中接受该消息的方法,最后一个参数是本条消息发送的字符串信息。比如上面例子中的代码就会调

 

作者:马三小伙儿
出处:http://www.cnblogs.com/msxh/p/7220741.html 
请尊重别人的劳动成果,让分享成为一种美德,欢迎转载。另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!

http://www.cnblogs.com/msxh/p/7220741.html