Unity3d Android SDK接入解析(四)通用的Android SDK接入中介軟體

來源:互聯網
上載者:User

標籤:

一、前言

接入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() {                @Override                public void run() {                    uaManager.login(sJson);                }            });        } catch (JSONException e) {            e.printStackTrace();        }    }
怎麼發送訊息回Unity
    // 發送訊息回Unity3d    public 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

楊光(atany)原創,轉載請註明博主與博文連結,未經博主允許,禁止任何商業用途。
博文地址:http://blog.csdn.net/yang8456211/article/details/52231305
部落格地址:http://blog.csdn.net/yang8456211
本文遵循“署名-非商業用途-保持一致”創作公用協議

Unity3d Android SDK接入解析(四)通用的Android SDK接入中介軟體

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.