Android 手游聚合SDK那些事

前言

在安卓游戲SDK這個(gè)技術(shù)領(lǐng)域呆了已經(jīng)有4年多华蜒,從游戲發(fā)行中的一員逐漸轉(zhuǎn)為游戲研發(fā)中的一員。從開始什么都不懂的菜鳥,摸爬滾打了幾年,多多少少對(duì)這個(gè)行業(yè)以及技術(shù)領(lǐng)域有了相對(duì)成熟的理解育灸。本文純概念性的東西較多,其主要是為了記錄一下這幾年知識(shí)昵宇,分享給有需要的人磅崭。也讓大家對(duì)這個(gè)游戲SDK行業(yè),有一個(gè)基本的理解趟薄。

1. 聚合SDK的概念

在手游行業(yè)里,聚合SDK就是一個(gè)中間層典徊,可以理解為連接游戲和渠道SDK交互的橋梁杭煎。舉個(gè)例子說明一下印象會(huì)更深刻,我們都會(huì)去買火車票卒落,買火車票不一定在火車站買羡铲,去12306官方網(wǎng)站購買或者電話訂票 ,也可以去代售點(diǎn)購買儡毕,中國13億人口可不是每個(gè)人都會(huì)網(wǎng)絡(luò)或者手機(jī)訂票 也切,還是有部分人選擇火車票代售點(diǎn)去買票。 鐵路局官網(wǎng)就好比是游戲研發(fā)方腰湾,火車票代售點(diǎn)就好比游戲發(fā)行方(提供聚合SDK)雷恃,鐵路局授權(quán)給火車票代售點(diǎn),代售點(diǎn)需要給官方授權(quán)費(fèi)费坊,代售點(diǎn)可以提供相關(guān)服務(wù)從購票者中獲取相關(guān)利益倒槐。換個(gè)技術(shù)角度來看代售點(diǎn)就是一個(gè)很好的代理模式。

1.1 游戲研發(fā)

游戲研發(fā)方就是專門開發(fā)游戲的公司附井,我們稱之為CP讨越。一般游戲研發(fā),很少會(huì)自己去推廣永毅、運(yùn)營自己的游戲把跨,術(shù)業(yè)有專攻,重點(diǎn)還是開發(fā)游戲?yàn)橹鳌?/p>

1.2 游戲發(fā)行

游戲發(fā)行方負(fù)責(zé)游戲推廣沼死,運(yùn)營以及相關(guān)技術(shù)服務(wù)着逐,發(fā)行方手里有資源,這種資源來自哪里呢?其中來自兩個(gè)點(diǎn)滨嘱,第一點(diǎn)自身平臺(tái)的用戶量(資源)峰鄙,第二點(diǎn)是渠道或者平臺(tái)方,例如華為渠道太雨,華為渠道的用戶量不用我說大家就應(yīng)該知道吟榴。

研發(fā)方有游戲,手里沒有很多資源 囊扳。發(fā)行方有豐富資源吩翻,沒有游戲團(tuán)隊(duì)來開發(fā)游戲∽断蹋互補(bǔ)一下商量如何共贏合作一起賺錢唄狭瞎,由發(fā)行方提供一套手游聚合SDK,其中包含核心的登錄 支付等功能搏予,研發(fā)方需要按照文檔定的標(biāo)準(zhǔn)熊锭,只要接入發(fā)行方的聚合SDK,剩下的什么都不用管了雪侥。發(fā)行方要做的就是把融合完成的游戲包上傳到各大游戲應(yīng)用商店和自己的官方平臺(tái)即可碗殷,發(fā)行方和研發(fā)方就可以坐等對(duì)賬分成咯。

1.3 渠道SDK

上面提到過資源速缨,用戶量這一個(gè)概念锌妻,一個(gè)游戲想要賺錢就需要一個(gè)龐大的用戶量,玩的人數(shù)越多游戲越吸引人意味著付費(fèi)率會(huì)很高旬牲。平臺(tái)上線了游戲之后仿粹,依賴用戶自己來下載游戲,起量是很慢的原茅,所以需要推廣吭历,如果使用推送讓用戶去下載,那么用戶體驗(yàn)會(huì)很差擂橘。所以需要讓那些有影響力的人來做有償推廣毒涧。例如華為游戲商店 、 oppo游戲商店 贝室、vivo游戲商店等 硬核聯(lián)盟契讲。這樣的渠道有著大量的用戶,所以我們?yōu)榱速嶅X要把游戲上架到各大游戲商店滑频,讓渠道平臺(tái)的大量用戶去玩捡偏。

1.3.1 游戲渠道SDK

上架游戲商店之前,我們需要在游戲中接入對(duì)應(yīng)聯(lián)運(yùn)SDK 峡迷。Huawei银伟、OPPO 你虹、ViVO等聯(lián)運(yùn)sdk是對(duì)應(yīng)自己的平臺(tái),其中就包含最核心的2個(gè)體系 登錄和支付彤避。

要上架我們渠道平臺(tái)傅物,我們給你做推廣 ,讓大量的用戶上我的平臺(tái)來玩你的游戲琉预。這就相當(dāng)于你上我家來做客董饰,就要按我們的規(guī)矩來,就需要使用我們提供的服務(wù)(渠道sdk API)圆米。

當(dāng)然了使用渠道的服務(wù)也是需要與渠道進(jìn)行資金的分成卒暂,一般情況下總收入的50%是劃到 渠道平臺(tái)的,剩下 50%是發(fā)行和研發(fā)來進(jìn)行分成娄帖。(特殊平臺(tái)例如騰訊 劃分比例會(huì)高一些)

1.3.2 官方渠道SDK

上游戲渠道要和平臺(tái)進(jìn)行比例分成也祠,那么上自己的游戲平臺(tái)收益就是百分百的完全不用跟別人分成總收入。官方渠道SDK是代表著自身的發(fā)行平臺(tái)近速,做發(fā)行的一般都會(huì)有屬于自己渠道平臺(tái)SDK诈嘿,自己平臺(tái)即可以封裝好給別人用,也可以接入到聚合SDK 中使用削葱。

官方SDK 本質(zhì)上跟渠道SDK沒什么區(qū)別奖亚,自身也是一個(gè)渠道SDK,擁有核心登錄和支付一系列API佩耳。它可以打成aar包接入到聚合SDK中 遂蛀,也可以作為一個(gè)獨(dú)立的渠道SDK 對(duì)外給別人使用谭跨。

1.4 聚合SDK是什么干厚?

上述給大家說了一些概念和名詞,可能有些朋友還是不好理解聚合sdk螃宙。那么我們一步步去分析講解蛮瞄。先拋棄聚合SDK的概念,先看一下一個(gè)游戲是怎么直接去接入渠道聯(lián)運(yùn)SDK的谆扎,我之前寫過博客Unity接入OPPO聯(lián)運(yùn)SDK這個(gè)大家可以去看看挂捅。

圖中為游戲直接接入OPPO網(wǎng)游SDK的登錄的邏輯,邏輯圖中數(shù)字對(duì)應(yīng)下列的描述數(shù)字

接入sdk邏輯圖.png
  1. 游戲客戶端調(diào)用SDK客戶端登錄API,如果滿足登錄條件的話堂湖,SDK客戶端攜帶數(shù)據(jù)去請(qǐng)求SDK服務(wù)器端進(jìn)行接口驗(yàn)證无蜂。

  2. 到第二步了說明SDK服務(wù)器端登錄驗(yàn)證通過训桶,然后會(huì)向SDK客戶端返回一些數(shù)據(jù)舵揭。

  3. 游戲客戶端 通過SDK客戶端的回調(diào)通知后得到數(shù)據(jù)午绳,一般情況下我們只需要得到token(令牌)和ssoid(用戶唯一標(biāo)識(shí))即可箱叁。

  1. 游戲客戶端獲取到token 和ssoid后 算色,拿數(shù)據(jù)給游戲服務(wù)器端發(fā)起驗(yàn)證請(qǐng)求灾梦。

  2. 游戲服務(wù)器得到token 和ssoid后妓笙,去請(qǐng)求SDK服務(wù)器(SDK服務(wù)器會(huì)有一份文檔對(duì)外提供寞宫,正常情況下是一個(gè)登錄請(qǐng)求的URL,游戲服務(wù)器按照要求進(jìn)行拼串加密請(qǐng)求即可)

  3. 到這一步說明SDK服務(wù)器的登錄二次驗(yàn)證是沒問題的辈赋,SDK服務(wù)器校驗(yàn)的結(jié)果傳回給游戲服務(wù)器

  4. 游戲客戶端收到了游戲服務(wù)端的成功結(jié)果,就可以進(jìn)行游戲的操作悟民。


上述7個(gè)步驟清晰的解釋了游戲直接和渠道SDK交互的邏輯,文章開頭介紹過游戲研發(fā)重點(diǎn)是放在游戲開發(fā)以及功能實(shí)現(xiàn)上智润,雖然游戲研發(fā)可以直接接入SDK渠道,但是考慮到一個(gè)問題钾麸,游戲需要推廣和運(yùn)營饭尝,游戲研發(fā)不擅長這些实撒。國內(nèi)的SDK渠道多如牛毛大大小小150個(gè)渠道應(yīng)該是有了知态,要是150個(gè)渠道都接入一遍想想就酸爽, 而且渠道SDK還需要不定時(shí)更新立叛,這無疑占用研發(fā)的大量時(shí)間精力。那么有沒有針對(duì)游戲研發(fā)方一個(gè)更好的方案呢秘蛇?游戲方只需要接入一個(gè)SDK 就可以完成N個(gè)游戲渠道SDK的上架呢 ,答案 有的 赁还,聚合SDK就這樣誕生了。


聚合SDK是連接渠道SDK和游戲方的一個(gè)橋梁或者說是中間層艘策, 何解呢蹈胡? 首先聚合SDK要和游戲渠道SDK進(jìn)行交互朋蔫,按照渠道SDK的文檔要求進(jìn)行接入斑举,渠道SDK N多個(gè)他們的api 都是大同小異區(qū)別不是很大富玷,那么把SDK共同點(diǎn)都抽象出來加以擴(kuò)展(對(duì)內(nèi)包容所有渠道SDK對(duì)外統(tǒng)一接口和回調(diào))赎懦,整合成一套完善的聚合框架提供給游戲研發(fā)方励两。研發(fā)方只需要接入一套聚合SDK就完活囊颅,剩下什么都不需要管可以安安心心去忙游戲相關(guān)的工作当悔。由發(fā)行方進(jìn)行游戲的打包分包上架游戲商店傅瞻。


下圖很好的體現(xiàn)出聚合SDK,作為聚合只有一個(gè)盲憎,需要兼容接入多家游戲(為了多賺錢不可能只跟一家研發(fā)方合作)嗅骄,多家渠道(上架越多意味著收入會(huì)更多一些)

聚合SDK.png

聚合SDK是連接游戲研發(fā)與渠道SDK的橋梁,讓他們可以通話饼疙,但是通話內(nèi)容是經(jīng)過聚合層加密的溺森,也就達(dá)到了發(fā)行公司代理發(fā)行運(yùn)營的目的∫っ校可以讓你們通話屏积,但不讓你們直接見面,再通俗的說磅甩,聚合==中間商炊林。下圖是加入聚合SDK的統(tǒng)一登錄流程,就是在原來研發(fā)直接接入渠道sdk基礎(chǔ)上卷要,多套了一層聚合客戶端和聚合服務(wù)端而已铛铁。聚合支付流程和聚合登錄流程差不多就不展示了。

聚合SDK登錄流程.jpg


章節(jié)小結(jié):

手游聚合SDK 和普通的SDK(例如統(tǒng)計(jì)却妨、定位)還是有很大區(qū)別的饵逐,最大的區(qū)別就是聚合SDK 需要提供一個(gè)統(tǒng)一的賬號(hào)體系和支付體系,分別對(duì)應(yīng)游戲登錄和支付功能彪标。

2. 聚合SDK對(duì)外接口設(shè)計(jì)

聚合SDK對(duì)外的設(shè)計(jì)就是一個(gè)抽象層倍权,對(duì)每個(gè)游戲來說,只需要接入抽象層足以捞烟,而對(duì)每個(gè)渠道SDK的接入薄声,就是抽象層的具體的實(shí)現(xiàn)。

考慮到一些渠道SDK 有的API(例如退出游戲)會(huì)沒有题画,建議通過反射來判斷當(dāng)前是否支持該方法默辨,例如isSupportFunction("exitSDK") 如果返回false ,說明當(dāng)前渠道不支持退出功能苍息,CP需要處理游戲自身的退出游戲方法缩幸。

    /**
     *判斷是否支持對(duì)應(yīng)方法
     * @param function
     * @return
     */
    public boolean isSupportFunction(String function) {
        Method method = null;
        try {
            method = getClass().getMethod(function, Map.class);
            return true;
        } catch (NoSuchMethodException e) {
            try {
                method = getClass().getMethod(function);
                return true;
            } catch (NoSuchMethodException e1) {

            }
        }
        return method != null;
    }
  1. 初始化
    • Application初始化:
      優(yōu)秀的SDK會(huì)考慮到兼容性,設(shè)計(jì)聚合SDK的時(shí)候要多給別人選擇性竞思,考慮到游戲有application邏輯的表谊,和沒有application邏輯,聚合SDK都要做處理盖喷。

    • Activity的初始化

  1. 登錄

統(tǒng)一登錄驗(yàn)證接口爆办,聚合客戶端接收渠道回調(diào)回來的參數(shù),去聚合服務(wù)器校驗(yàn)课梳。聚合客戶端會(huì)提供給cp 登錄成功 距辆、登錄失敗 余佃、登錄取消三個(gè)回調(diào)狀態(tài),聚合服務(wù)器校驗(yàn)成功 cp會(huì)得到token 和uid 等信息跨算,格式為json

  1. 支付

統(tǒng)一支付驗(yàn)證接口咙冗,跟登錄差不多 不做描述。備注下:訂單號(hào)不要過長不能超過30個(gè)字符

  1. 注銷(切換賬號(hào))

  2. 退出

  3. 生命周期

設(shè)計(jì)的時(shí)候生命周期最好都要考慮全

 @Override
    protected void onStart() {
        super.onStart();     
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onRestart() {
        super.onRestart();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }
    @Override
    public   void  onRequestPermissionsResult(int requestCode, String[] permissions,  int[] grantResults){
        super.onRequestPermissionsResult(requestCode,permissions,grantResults);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    }
  1. 渠道數(shù)據(jù)上報(bào)
    正常情況下集合中的value值是從游戲哪里獲取真實(shí)數(shù)據(jù) 漂彤,傳輸格式j(luò)son雾消。文中代碼僅供演示
        private static Map<String, String> mRoleInfo = null;

        mRoleInfo = new HashMap<String, String>();
        mRoleInfo.put("roleId", "123456");// 當(dāng)前登錄的玩家角色I(xiàn)D,若無,可傳入userid
        mRoleInfo.put("roleName", "角色名稱");// 當(dāng)前登錄的玩家角色名,不能空
        mRoleInfo.put("roleLevel", "10");// 當(dāng)前登錄的玩家角色等級(jí)挫望,不能為空立润,必須為數(shù)字,且不能為null媳板,若無桑腮,傳入0
        mRoleInfo.put("serverId", "1");// 當(dāng)前登錄的游戲區(qū)服ID,不能為空蛉幸,必須為數(shù)字破讨,若無,傳入0
        mRoleInfo.put("serverName", "服務(wù)器名稱");// 當(dāng)前登錄的游戲區(qū)服名稱,不能為空,長度不超過50奕纫,不能為null提陶,若無,傳入“無”
        mRoleInfo.put("vip", "vip20");// 玩家VIP等級(jí)   若無匹层,傳入0
        mRoleInfo.put("moneyNum", "100金幣");// 當(dāng)前玩家身上擁有的游戲幣數(shù)量  若無隙笆,傳入“無”
        mRoleInfo.put("roleLevelUpTime", System.currentTimeMillis() / 1000 + "");// 角色等級(jí)變化時(shí)間,僅創(chuàng)建角色時(shí)傳入,同一角色創(chuàng)建時(shí)間不可變(單 位:秒 )升筏,長度 10
        mRoleInfo.put("roleCTimeroleCTime", System.currentTimeMillis() / 1000 + "");// 角色創(chuàng)建時(shí)間撑柔,僅創(chuàng)建角色時(shí)傳入,同一角色創(chuàng)建時(shí)間不可變(單 位:秒 ),長度 10
  • 選擇區(qū)服

  • 創(chuàng)建角色

  • 選擇角色

  • 進(jìn)入游戲

  • 角色升級(jí)時(shí)

  • 退出游戲

    對(duì)應(yīng)場景(這些場景滿足國內(nèi)大部分SDK)接收游戲傳來的數(shù)據(jù) 上報(bào)給渠道SDK您访,這個(gè)一般渠道SDK做統(tǒng)計(jì)用

  1. 實(shí)名認(rèn)證

    2020年新增的一個(gè)接口 铅忿,SDK渠道為了響應(yīng)國家號(hào)召,所以聚合也需要提供接口給CP


3.聚合SDK開發(fā)規(guī)范

開發(fā)一套聚合SDK灵汪,會(huì)提供給多個(gè)CP去使用檀训,我們無法保證CP開發(fā)的游戲,是否有接入其他的SDK识虚,或者自身使用到了第三方的SDK肢扯。所以我們?cè)陂_發(fā)SDK時(shí)候要注意以下幾點(diǎn)妒茬。

  1. 依賴第三方庫導(dǎo)致的沖突

說明:作為聚合SDK担锤,應(yīng)該盡量少使用開源庫,或者說不用開源庫乍钻,而是通過手寫網(wǎng)絡(luò)框架肛循,手寫數(shù)據(jù)庫等等铭腕,主要是考慮兩個(gè)方面:

  • 減小SDK體積

  • 避免渠道和CP接入的時(shí)候發(fā)生依賴沖突

曾經(jīng)遇到過這樣的場景 渠道用了低版本的v4包 ,游戲給的母包(接入好聚合sdk的游戲包apk)用了高版本的 v4包 多糠。導(dǎo)致一個(gè)問題拆包合并覆蓋資源時(shí)候smali文件丟失累舷,重新生成的渠道包 各種崩潰閃退。簡述一下這個(gè)問題最后解決方案 就是刪除掉渠道低版本v4包采用高版本的夹孔。v4向下兼容

規(guī)范:應(yīng)該盡可能地避免依賴過多的第三方庫被盈。特別是一些知名的庫,比如android support庫搭伤,okhttp3, glide, eventbus等等只怎。 如果你確實(shí)要使用,也可以使用工具將這些開源庫的包名改為您自定義的名稱怜俐。

  1. 聚合SDK中的資源文件命名沖突

說明:聚合SDK中可能會(huì)引用的布局資源身堡,如果與CP或者渠道SDK資源重名會(huì)很麻煩。資源重名沖突的問題一般會(huì)出現(xiàn)在偏門或者小眾的sdk上拍鲤。比較出名大眾SDK都會(huì)對(duì)資源命名有嚴(yán)格要求贴谎。舉個(gè)例子sdk中有l(wèi)ayout_main.xml, 游戲母包或者渠道SDK中也帶有同名的layout_main.xml季稳。在解包合并資源時(shí)候就會(huì)出現(xiàn)資源丟失奔潰的問題擅这。這也是為什么強(qiáng)調(diào)資源命名一定區(qū)分開。

規(guī)范:資源等命名景鼠,需要加上自己獨(dú)特的前綴蕾哟,避免與CP或渠道SDK沖突。例如
baidu_layout.xml,baidu_dimen.xml.資源id的命名同樣如此莲蜘。一定要規(guī)范谭确,不然會(huì)有很多麻煩。

  1. 聚合SDK中的所使用資源索引(R.java)直接引用,會(huì)導(dǎo)致接入游戲中票渠,資源引用丟失或崩潰等情況

規(guī)范: 所有對(duì)res文件下資源的引用逐哈,代碼統(tǒng)一使用context.getResources().getIdentifier() 動(dòng)態(tài)方式獲取資源id

技術(shù)博客:Android動(dòng)態(tài)獲取資源ID之getIdentifier()

  1. 聚合SDK對(duì)外接入文檔規(guī)范

說明:考慮到CP可能是國內(nèi)的研發(fā)團(tuán)隊(duì) 也可能是歪果仁,所以文檔要提供兩份 一份國內(nèi)簡體中文版 和國外英文版兩套文檔问顷。文檔內(nèi)容一定要簡單明了昂秃,不要做過多贅述,層次要清晰杜窄,文檔內(nèi)容涉及的專業(yè)術(shù)語要寫的官方些肠骆。常見的SDK問題和聚合SDK架構(gòu)邏輯要描述清楚,這樣能減少不必要的溝通成本塞耕。

文檔規(guī)范:

  • 聚合SDK文檔概要說明

  • 更新日志

  • 快速升級(jí)

  • 接入準(zhǔn)備與環(huán)境配置

  • 聚合SDK架構(gòu)邏輯圖

  • SDK接口(每個(gè)接口都要標(biāo)注好必接和選接)

  • SDK接入常見問題

4.聚合SDK常見的一些問題蚀腿,以及解決方案

  • HTTP和HTTPS
    Android9.0 默認(rèn)是禁止所有的http請(qǐng)求的,作為聚合SDK是需要兼容做下兼容的。避免游戲工程或者渠道SDK使用HTTP導(dǎo)致崩潰出現(xiàn)莉钙。我列出兩種方案廓脆,供大家參考。

    1. 在建立res/xml/network_security_config.xml磁玉,
      <?xml version="1.0" encoding="utf-8"?>
      <network-security-config>
          <base-config cleartextTrafficPermitted="true" />
          <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">gamecfg-mob.ubi.com</domain>
          </domain-config>
      </network-security-config>
    

    在清單文件的application中添加android:networkSecurityConfig="@xml/network_security_config"

    1. 在清單文件的application中添加 屬性 android:usesCleartextTraffic="true" (這種方式比較省事)
  • Java版本管理

      compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_1_8
     }
    
    

    主要為了兼容停忿,這種設(shè)置國內(nèi)渠道SDK很少 ,海外的SDK比較多

  • 權(quán)限問題
    關(guān)于權(quán)限問題蚊伞,聚合SDK可以做成工具類或者做成一個(gè)權(quán)限庫對(duì)CP開放接口席赂。可能CP也會(huì)對(duì)權(quán)限做處理时迫,如果同時(shí)獲取氧枣,在玩家還沒給權(quán)限的情況下,有些手機(jī)是會(huì)重復(fù)彈出權(quán)限詢問框的别垮,所以這個(gè)權(quán)限問題最好是讓CP控制便监。

  • 支付補(bǔ)單邏輯
    無論是聚合客戶端還是聚合服務(wù)端,都有自動(dòng)補(bǔ)單的能力碳想,聚合服務(wù)器一定要完善烧董,對(duì)新的補(bǔ)單請(qǐng)求要做及時(shí)處理。聚合客戶端也要做好本地?cái)?shù)據(jù)的存儲(chǔ)以及定時(shí)的清除補(bǔ)單數(shù)據(jù)胧奔,在初始化或者支付前校驗(yàn)一下是否有調(diào)單的訂單逊移。針對(duì)調(diào)單的問題大部分是單機(jī)游戲 。網(wǎng)絡(luò)游戲正常情況下CP方會(huì)有調(diào)單處理的邏輯龙填。但也并非絕對(duì)胳泉。

  • Android Studio 與Eclipse
    考慮到CP特殊性,會(huì)提供AS和Eclipse兩種DEMO工程岩遗,對(duì)于海外的一些CP,部分還是有用Eclipse做接入的稚疹。正常情況下提供aar文件灵妨,eclipse是不支持aar文件的溶浴,但是可以把a(bǔ)ar文件拆分下茬射,aar本質(zhì)上也是個(gè)壓縮包。

  • 方法超限的問題
    方法超限問題在國內(nèi)的SDK比較常見的 例如接入百度和奇虎360的網(wǎng)游聯(lián)運(yùn)SDK,考慮到這種情況梆靖,在設(shè)計(jì)聚合SDK的時(shí)候控汉,在application里會(huì)處理對(duì)應(yīng)的邏輯。在跟CP對(duì)接時(shí)候文檔一定要明確 版本避免與CP和渠道方的沖突返吻。關(guān)于MultiDex的用法可參考我寫過的文章:MultiDex使用和原理解析

  • 部分高版本機(jī)型 出現(xiàn)底部欄黑邊情況
    在清單文件中application屬性里設(shè)置android:resizeableActivity = “true”并加上
    <meta-data android:name="android.max_aspect" android:value="2.4"/>屬性姑子,
    這倆屬性配套使用。如果還會(huì)不行在Activity的onCreate()里調(diào)用此方法测僵。

      private void SetScreen() {
          Window window = getWindow();
          //使內(nèi)容出現(xiàn)在status bar后邊街佑,如果要使用全屏的話再加上View.SYSTEM_UI_FLAG_FULLSCREEN
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
              Log.i("VERSION_CODES", "Build.VERSION_CODES.JELLY_BEAN");
              window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
          }
          //設(shè)置頁面全屏顯示
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
              Log.i("VERSION_CODES", "Build.VERSION_CODES.P");
              WindowManager.LayoutParams lp = window.getAttributes();
              lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
              //設(shè)置頁面延伸到劉海區(qū)顯示
              window.setAttributes(lp);
          }
      }
    
    
  • 關(guān)于異形屏的問題
    異形屏是最近這一兩年出來的,每個(gè)手機(jī)廠商平臺(tái)提供對(duì)應(yīng)的異形屏適配的文檔,我們可以根據(jù)文檔提供的方式封裝成工具類舆乔, 對(duì)外供CP調(diào)用岳服。這里我就不做展示了很簡單剂公。
  • 部分機(jī)型廣告SDK問題
    聚合SDK根據(jù)需求封裝過廣告的插件 希俩,一些特殊的渠道廣告SDK ,例如OPPO和VIVO的廣告SDK纲辽,只能在OPPO和VIVO手機(jī)上才能做廣告展示颜武。很坑,這個(gè)我覺得需要記錄一下拖吼。

結(jié)語

本人表述能力有限鳞上,大家多多諒解,希望這篇文章能帶給你一些幫助吊档,如果還是沒有理解歡迎私信騷擾我篙议。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過簡信或評(píng)論聯(lián)系作者怠硼。
  • 序言:七十年代末鬼贱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子香璃,更是在濱河造成了極大的恐慌这难,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葡秒,死亡現(xiàn)場離奇詭異姻乓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)眯牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門蹋岩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人学少,你說我怎么就攤上這事星澳。” “怎么了旱易?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵禁偎,是天一觀的道長。 經(jīng)常有香客問我阀坏,道長如暖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任忌堂,我火速辦了婚禮盒至,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己枷遂,他們只是感情好樱衷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著酒唉,像睡著了一般矩桂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上痪伦,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天侄榴,我揣著相機(jī)與錄音,去河邊找鬼网沾。 笑死癞蚕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辉哥。 我是一名探鬼主播桦山,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼醋旦!你這毒婦竟也來了恒水?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤浑度,失蹤者是張志新(化名)和其女友劉穎寇窑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箩张,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甩骏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了先慷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饮笛。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖论熙,靈堂內(nèi)的尸體忽然破棺而出福青,到底是詐尸還是另有隱情,我是刑警寧澤脓诡,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布无午,位于F島的核電站,受9級(jí)特大地震影響祝谚,放射性物質(zhì)發(fā)生泄漏宪迟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一交惯、第九天 我趴在偏房一處隱蔽的房頂上張望次泽。 院中可真熱鬧穿仪,春花似錦、人聲如沸意荤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玖像。三九已至紫谷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間御铃,已是汗流浹背碴里。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工沈矿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留上真,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓羹膳,卻偏偏與公主長得像睡互,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子陵像,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354