一、簡介

  通常一款游戲開發(fā)到后期,一般都會涉及到第三方SDK的接入與集成,對于不熟悉SDK接入的同學(xué)來說,接SDK每次都是云里霧里,而熟悉SDK接入的同學(xué)又覺得不斷地重復(fù)做接入SDK工作這樣沒有成就感,太尼瑪無聊了(Android渠道一弄就十幾個,直接吐血)。其實通常情況下接入SDK都是很簡單的一個過程,本系列博客就讓馬三和大家從小白開始,從零基礎(chǔ)開始學(xué)習(xí)如何接入SDK以及一些常見的SDK的接入流程。本系列博客規(guī)劃為以下幾篇:

  • SDK接入與集成——小白入門篇(介紹環(huán)境搭建以及Unity和Android的基本交互與調(diào)用)

  • SDK接入與集成——信鴿SDK篇(介紹消息推送框架--信鴿SDK的接入)

  • SDK接入與集成——QQ與微信SDK篇(都是騰訊開放平臺的,就放在一起學(xué)了)

  • SDK接入與集成——科大訊飛SDK篇(游戲中的語音通信和語音識別會用到此SDK)

  • SDK接入與集成——百度地圖SDK篇(做LBS游戲必不可少)

  • SDK接入與集成——第三方SDK接入解決方案AnySDK篇

  • SDK接入與集成——構(gòu)建自己的Android集成多SDK框架篇

  先挖了這么多坑,以后慢慢填吧,放心博主肯定不會太監(jiān)的。

回到頂部

二、淺談常用的兩種接入方案

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

  其實游戲SDK接入發(fā)展到現(xiàn)在,已經(jīng)有很多成熟的第三方SDK接入解決方案了,比如AnySDK,ShareSDK,U8SDK等等。這些第三方SDK接入解決方案的整個接入過程,不改變?nèi)魏蜸DK的功能、特性、參數(shù)等,對于最終玩家而言是完全透明無感知的。讓CP商能有更多時間更專注于游戲本身的品質(zhì)。第三方SDK包括了渠道SDK、用戶系統(tǒng)、支付系統(tǒng)、廣告系統(tǒng)、統(tǒng)計系統(tǒng)、分享系統(tǒng)等等。利用他們可以輕松快速接入第三方SDK。

  第三方SDK的統(tǒng)一驗證流程基本如下:

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

2.手動接入SDK

  既然上面說的第三方解決方案那么好,為什么我們還有手動去接入SDK呢?造輪子就這么上癮?其實接入了一些第三方的SDK解決方案以后,我們有的游戲數(shù)據(jù)是要經(jīng)過他們的服務(wù)器的,對于一些游戲廠商來說,不想讓自己的數(shù)據(jù)經(jīng)過別人的服務(wù)器,或者需要對驗證服務(wù)器有完全自主的控制權(quán),那么必然要手動接入各種SDK了。另外還有一些奇奇怪怪,非常詭異的SDK,我們也是要手動去接入的,不能都指望第三方的集成。而且作為一名合格的猿類來收,知其然更要知其所以然,掌握SDK的接入原理和過程很有必要。

回到頂部

三、開始接入!Unity與Android的交互

  前面啰嗦了那麼多,到這里終于可以開始實戰(zhàn)操作了。

1.Android開發(fā)環(huán)境搭建

  關(guān)于Android環(huán)境的搭建,網(wǎng)上已經(jīng)有很多博客了,介紹的很詳細(xì),馬三就不在這里水了。這里給大家安利一個關(guān)于Android開發(fā)工具的好網(wǎng)站:http://www.androiddevtools.cn/ 。上面提供了很多可用的AndroidADK國內(nèi)鏡像和教程。

2.Android端的開發(fā)工作

 ?。?)打開IDE建立一個空的Android庫工程,這里我用Eclispe舉例。注意Min Required SDK最好選擇4.0以上,要不然還需要引入android-support-v7兼容包,比較麻煩,之后我們可以把這個Min Required SDK 再該回來的。需要注意的兩步已經(jīng)截圖了,剩下一路Next操作即可。注意包名和勾選Mark this project as a library選項。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 ?。?)導(dǎo)入Classes.jar包到Android工程中

  Unity和Android做交互,他們兩個之間不認(rèn)識肯定,沒法直接通信,因此需要一個中間的搭橋牽線的人,Classes.jar就起到了這個作用。Classes.jar是由Unity提供給我們的,我們需要找到它并且引入到我們的Android項目中。Claess.jar的路徑一般如下 X盤:\xxx目錄\Unity\Editor\Data\PlaybackEngines\androidplayer\release\bin\classes.jar(不同的計算機(jī)上,這個位置可能會有所不同,大家按照自己的路徑添加即可)。我們找到它直接拖到我們的Android工程的libs目錄下。然后在它上面右鍵,將其添加到Build Path中。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

  添加到Build Path成功以后,工程是這個樣子的。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

  (3)編寫Android端的代碼

  我們在Android端編寫一些代碼,提供一些接口來供Unity一會的調(diào)用。打開我們的MainActivity.java,然后添加代碼。需要注意的是,讓我們的MainActivity繼承Jar包中的UnityPlayerActivity類,這樣,Unity才能調(diào)的到哦,缺什么包,直接讓Eclipe自動導(dǎo)下包即可,快捷鍵ctrl+shift+o。對了,還需要把 setContentView(R.layout.activity_main); 這段代碼注釋掉,要不然會顯示Android的默認(rèn)布局文件,上面就一個 Hello World。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 

  簡單的寫了幾個普通方法和一個靜態(tài)方法,供一會的測試調(diào)用。(無論是靜態(tài)方法還是普通方法,在Unity中都是可以調(diào)用的到的)MainActicity.java的代碼內(nèi)容如下:

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 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調(diào)用的求和函數(shù)46      * @param x47      * @param y48      * @return49      */50     public int Sum(int x, int y) {51         return x + y;52     }53 54     /**供Unity調(diào)用的比較最大值函數(shù)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調(diào)用的顯示吐司的函數(shù)65      * @param str66      */67     public void MakeToast(String str) {68         Toast.makeText(this, str, Toast.LENGTH_LONG).show();69     }70 71     72     /**供Unity調(diào)用的自加一函數(shù)73      * @param x74      * @return75      */76     public int AddOne(int x) {77         return x + 1;78     }79 80     81     /**供Unity調(diào)用的靜態(tài)方法,單例類,返回當(dāng)前的Activity對象82      * @return83      */84     public static MainActivity GetInstance() {85         return instance;86     }87     88     89     /**供Unity調(diào)用的函數(shù),此函數(shù)會回調(diào)指定的一個Unity中的方法,完成數(shù)據(jù)的雙向交互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 }

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 

   (4)導(dǎo)出我們的Android項目為Jar包供Unity調(diào)用

  在我們的項目上面右鍵,然后選擇Export,選擇Java目錄下的 Jar file。因為沒有用到第三方的jar包或者lib庫,因此只要勾選src/和res/目錄導(dǎo)出為jar包即可。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 ?。?)Unity端工程的開發(fā)

  建立一個新的空Unity工程,然后在Asset/目錄下建立如下路徑的文件夾:Plugins/Android。從名字就可以看出來,這個文件夾是用來存放安卓的插件的。然后將我們上面剛剛導(dǎo)出的SDKBase.jar 包導(dǎo)入到這個目錄下,并且將Andoird工程目錄下的,libs/ 、res/ 、AndroidMainFest.xml 都復(fù)制到該路徑下。

  需要特別注意的是要將Unity 項目中 libs下的classes.jar文件刪除掉,這個就是上面提到的那個起到中介作用的jar包,一定要刪掉!一定要刪掉!一定要刪掉!(重要的事情說三遍,網(wǎng)上不少教程都是針對Unity老版的教程,沒有提到要刪除這個classes.jar包,結(jié)果在Unity 5.x中打包肯定會出錯)。出錯截圖如下所示。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn) 移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

  然后我們建立一個場景,簡單地在里面放上一些Label和輸入框、按鈕,供我們驗證交互操作。并且編寫一個腳本(MessageHandler.cs即是我創(chuàng)建的腳本), 在其中編寫用來調(diào)用Jar包的C#方法,然后將按鈕和這些函數(shù)綁定(Unity基本操作,不贅述了)。

  移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn) 移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

  MessageHandler.cs 腳本的內(nèi)容如下,函數(shù)的功能看注釋就行了,寫得很全。

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 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"這兩個參數(shù)都是固定的19         //UnityPlayerActivity里面對其進(jìn)行了處理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         //注意,這里使用的就不是之前默認(rèn)的com.unity3d.player.UnityPlayer,而是需要傳入自己的類(實現(xiàn)了需要調(diào)用相應(yīng)方法的類)29         //因為默認(rèn)的UnityPlayer中是沒有我們所需要的方法的,所以需要加載自己的類30         AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");31         //調(diào)用Java中的靜態(tài)方法,單例模式,返回當(dāng)前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         //調(diào)用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         //調(diào)用Java中的一個方法,該方法會回調(diào)Unity中的指定的一個方法,這里會回調(diào)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 調(diào)用Toast");65     }66 }

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

 

  通過上面的代碼,我們就可以看出來,想在Unity中調(diào)用Android的代碼,主要涉及到了兩個類。AndroidJavaClass 和 AndroidJavaObject 。這兩個類在Unity API手冊里面有詳細(xì)的解釋。

  下面的代碼是獲取到對應(yīng)包名的java.lang.Class實例,這里獲取到的是com.unity3d.player.UnityPlayer類。

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

  下面的代碼是獲取到UnityPlayer類中的靜態(tài)字段,它的返回值類型是AndroidJavaObject對象。

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

  通過以上兩行代碼,我們可以獲取到這個AndroidJavaObject 對象,然后用 AndroidJavaObject 對象就可以任意地調(diào)用Android中的靜態(tài)和非靜態(tài)函數(shù)了。其中兩個函數(shù)中的字符串參數(shù) "com.unity3d.player.UnityPlayer" 和 "currentActivity" 都是固定的寫法,我們不用去改變。

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

AndroidJavaObject構(gòu)造函數(shù),根據(jù)類名返回AndroidJavaObject對象
Call調(diào)用Android代碼中的非靜態(tài)方法
CallStatic調(diào)用Android代碼中的靜態(tài)方法
DisposeIDisposable 回調(diào)
Get獲取Android代碼中的非靜態(tài)字段
GetRawClass獲取一個指向Java class的原始引用
GetRawObject獲取一個指向Java object的原始引用
GetStatic獲取Android代碼中的靜態(tài)字段
Set設(shè)置Android代碼中的非靜態(tài)字段
SetStatic設(shè)置Android代碼中的靜態(tài)字段

 

  另外,我們還有第二種方法去訪問Java的代碼,那就是利用我們之前在Java代碼中寫的 GetInstance() 靜態(tài)方法,它會返回一個MainActivity的實例,我們拿到這個實例以后,就能訪問里面的方法和字段了。需要注意的是此時的AndroidJavaClass構(gòu)造函數(shù)中傳遞的字符串就不是 "com.unity3d.player.UnityPlayer" 了。而是要傳入自己的包名,比如代碼中的 “com.mx.sdkbase.MainActivity” 。代碼如下:

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

        int a = Convert.ToInt32(inputFieldA.text);        //注意,這里使用的就不是之前默認(rèn)的com.unity3d.player.UnityPlayer,而是需要傳入自己的類(實現(xiàn)了需要調(diào)用相應(yīng)方法的類)        //因為默認(rèn)的UnityPlayer中是沒有我們所需要的方法的,所以需要加載自己的類
        AndroidJavaClass jc = new AndroidJavaClass("com.mx.sdkbase.MainActivity");        //調(diào)用Java中的靜態(tài)方法,單例模式,返回當(dāng)前Activity實例
        AndroidJavaObject jo = jc.CallStatic<AndroidJavaObject>("GetInstance");
        resultLabel.text = "AddOne" + jo.Call<int>("AddOne",a);

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

  不止Unity可以調(diào)用Android的代碼,Android也可以反過來回調(diào)Unity的代碼。下面這段代碼就是用來回調(diào)Unity函數(shù)的:

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

    /**供Unity調(diào)用的函數(shù),此函數(shù)會回調(diào)指定的一個Unity中的方法,完成數(shù)據(jù)的雙向交互
     * @param str     */
    public void CallUnityFunc(String str){
        str=str+"Android Call Unity.";
        String ReceiveObject="MessageHandler";
        String ReceiverMethod="Receive";
        UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str);
    }

移動開發(fā)培訓(xùn),Android培訓(xùn),安卓培訓(xùn),手機(jī)開發(fā)培訓(xùn),手機(jī)維修培訓(xùn),手機(jī)軟件培訓(xùn)

  利用UnityPlayer.UnitySendMessage(ReceiveObject, ReceiverMethod, str); 就可以返回過來回調(diào)一個Unity中的方法,完成Unity和Android的雙向通信。其中第一個參數(shù)是接受該回調(diào)的gameobject名稱,第二個參數(shù)是掛載在該gameobject上面的一個腳本中接受該消息的方法,最后一個參數(shù)是本條消息發(fā)送的字符串信息。比如上面例子中的代碼就會調(diào)

 

作者:馬三小伙兒
出處:http://www.cnblogs.com/msxh/p/7220741.html 
請尊重別人的勞動成果,讓分享成為一種美德,歡迎轉(zhuǎn)載。另外,文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!

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