Android多渠道打包(定制化馬甲包)

1剿干、為什么要進行多渠道打包蜂怎?

安卓應(yīng)用商店(一個商店也叫做一個渠道,如豌豆莢置尔,360手機助手杠步,應(yīng)用寶)眾多,大大小小幾百個榜轿,每當我們發(fā)新版本時幽歼,需要將Android客戶端分發(fā)到各個應(yīng)用市場,為了統(tǒng)計這些市場的效果(下載量差导、活躍數(shù)等),需要有一種方法來唯一標識它們猪勇,所以才有了多渠道打包设褐。

2、如何統(tǒng)計各個渠道的下載量、活躍數(shù)助析?

現(xiàn)在有比較成熟的第三方應(yīng)用幫我們實現(xiàn)統(tǒng)計功能(比如友盟)犀被,統(tǒng)計的本質(zhì)就是收集用戶信息傳輸?shù)胶笈_,后臺生成報表外冀,幫助我們跟蹤分析并完善app寡键。通過android系統(tǒng)的方法已經(jīng)可以獲取到引用版本號,版本名稱雪隧,系統(tǒng)版本西轩,機型等各種信息,唯獨應(yīng)用商店(渠道)的信息我們是沒有辦法從系統(tǒng)獲取到的脑沿,所以我們就人為的在apk里面添加渠道信息(其實就用一個字段進行標識藕畔,如wandoujia360庄拇,yingyongbao)注服,我們只要把這些信息打包到apk文件并將信息傳輸?shù)胶笈_,后臺根據(jù)這個標識措近,可以統(tǒng)計各個渠道的下載量了溶弟。
多渠道打包只需要關(guān)注兩件事情:

    1. 將渠道信息寫入apk文件
    1. 將apk中的渠道信息傳輸?shù)浇y(tǒng)計后臺

3、使用Gradle進行多渠道批量打包**

  1. 通常都是在在AndroidManifest.xml中加入渠道區(qū)分標識寫入一個meta標簽:

    <meta-data   
       android:name="channel"    
       android:value="${channel}" 
    />
    
  2. 在app目錄下在build.gradle中配置productFlavors添加如下代碼:

    productFlavors {
        qihu360 {} // 360手機助手
        yingyongbao {} // 騰訊應(yīng)用寶
        wandoujia {} // 豌豆莢
        baidu {} // 百度手機助手
        miui {} // 小米
        flyme {} // 魅族
        lenovo {} // 聯(lián)想-樂商店
        oppo {} // Oppo-可可軟件商店
        huawei {} // 華為
        vivo {} // vivo
        hiapk {} // 安卓市場
        sj91 {} // 91手機助手
        sogou {} // 搜狗手機市場
        sohu {} // 搜狐應(yīng)用中心
        taobao {} // 淘寶手機助手
        gfan {} // 機鋒
        appchina {} // 應(yīng)用匯
        mumayi {} // 木螞蟻
        wangyi163 {} // 網(wǎng)易應(yīng)用
        nduoa {} // N多市場
        mm10086 {} // MM商城-中國移動
        wostore {} // WO商店
        youyi {} // 優(yōu)異
        uc {} // UC+開發(fā)平臺
        anzhi {} // 安智市場
        google {} // google play
        amazon {} // 亞馬遜
    }
    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [channel: name]
    }
    

    AndroidStudio的Build -> Generate signed apk打簽名包時即可選擇設(shè)置渠道:

    Paste_Image.png

  3. 在代碼中獲取渠道信息:

public static String getFlavorChannel(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            ApplicationInfo appInfo = pm.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return appInfo.metaData.getString("channel");
        } catch (PackageManager.NameNotFoundException ignored) {
        }
        return "";
    }
  1. 在android studio中測試不同渠道的apk瞭郑。
Paste_Image.png

4.APP定制渠道包(馬甲包)

在App的開發(fā)過程中辜御,經(jīng)常會遇到產(chǎn)品或者運營的同事提出要制作馬甲包的需求;馬甲包簡單來說就是原APP的小號凰浮,與原APP包除了包名我抠,應(yīng)用名稱、圖標等給用戶加以區(qū)分的東西袜茧,其他功能基本不變亦或者只采用原App的部分功能的APP包菜拓。

  1. ApplicationId,版本號
    Android 應(yīng)用都有自己的包名笛厦。包名是設(shè)備上每個應(yīng)用程序的唯一標識纳鼎,同樣也是在各個下載平臺的唯一標識。就是說裳凸,假如你已經(jīng)使用某個包名來發(fā)布應(yīng)用贱鄙,就不能再去改變應(yīng)用的包名,因為這樣做會導(dǎo)致你的應(yīng)用被視為一個全新的應(yīng)用姨谷,你現(xiàn)有的用戶也不會收到應(yīng)用的更新通知逗宁。
    隨著渠道越來越多,不同渠道對應(yīng)用的要求也不盡相同梦湘。有時候我們需要發(fā)布不同的版本瞎颗,例如 pro件甥,hd 版本,支持用戶可以下載安裝不同的版本哼拔。那么我們需要設(shè)置不同的ApplicationId和對應(yīng)的版本號引有, 同時要與 PackageName 解耦合。
  • 代碼中引用的 R 類要保持不變倦逐;
  • 在構(gòu)建不同版本的應(yīng)用時譬正,對應(yīng)的(引用了 R 的) .java 源文件也不能改動。

那么我們只需要在productFlavors對應(yīng)的渠道中指定applicationIdversionCode檬姥,versionName曾我,例我們指定GooglePlayapplicationId:

 productFlavors {
        GooglePlay {
            //指定這個渠道的版本號
            versionCode 2
            versionName "1.2"
            //指定區(qū)別于其他渠道的 applicationId
            applicationId "com.liujc.androidtools.hd"
        } 
        yingyongbao {} // 騰訊應(yīng)用寶
        wandoujia {} // 豌豆莢
        baidu {} // 百度手機助手
        miui {} // 小米
        //其他...
    }
  1. BuildConfig
    Gradle會在generateSources階段為flavor生成一個BuildConfig.java文件。BuildConfig類默認提供了一些常量字段穿铆,比如應(yīng)用的版本名(VERSION_NAME)您单,應(yīng)用的包名(PACKAGE_NAME)等。更強大的是荞雏,開發(fā)者還可以添加自定義的一些字段虐秦。下面的示例假設(shè)debug版開啟LOG功能,使用debug的api凤优,而release版則使用不開啟LOG和使用release時的api:
    buildTypes {
        debug {
            // debug模式下悦陋,顯示log
            buildConfigField("boolean", "LOG_DEBUG", "true")
            buildConfigField ("String", "API_HOST", "\"http://api.test.com\"")//debug API Host
        }
        release {
            // release模式下,不顯示log
            buildConfigField("boolean", "LOG_DEBUG", "false")
            buildConfigField("String", "API_HOST", "\"http://api.release.com\"")//release API Host
        }
    }
    
    那么代碼中就可以使用 BuildConfig.LOG_DEBUG 和 BuildConfig.API_HOST 了筑辨。
    備注: 這里簡單介紹下buildConfigField 方法俺驶,可以發(fā)現(xiàn)其有三個參數(shù):
    /**
     * Adds a new field to the generated BuildConfig class.
     *
     * <p>The field is generated as: {@code <type> <name> = <value>;}
     *
     * <p>This means each of these must have valid Java content. If the type is a String, then the
     * value should include quotes.
     *
     * @param type the type of the field
     * @param name the name of the field
     * @param value the value of the field
     */
    public void buildConfigField(
            @NonNull String type,
            @NonNull String name,
            @NonNull String value)
    
    String type 要創(chuàng)建的字段類型 如上面的String與boolean
    String name 要創(chuàng)建的字段名 如上面的API_HOST與LOG_DEBUG
    String value 創(chuàng)建此字段的值 如上面的"\"http://api.release.com\""與"true"
    但這里要注意一點就是,當創(chuàng)建的類型為String時棍辕,定義value的時候要注意加上字符串不能缺少的雙引號""暮现,由于參數(shù)本身要傳入的類型也是String,所以我們在添加的時候加上轉(zhuǎn)義字符楚昭。
  1. 控制是否自動更新
    一般應(yīng)用在啟動時都會默認檢查客戶端是否有更新栖袋,如果有更新就會提示用戶下載。但是有些渠道和應(yīng)用市場不允許這種默認行為抚太,所以在適配這些渠道時需要禁止自動更新功能塘幅。
    解決的思路是提供一個配置字段,應(yīng)用啟動的時候檢查該字段的值以決定是否開啟自動更新功能尿贫。使用flavor可以完美的解決這類問題电媳。甚至可以在productFlavors對應(yīng)的渠道號進行區(qū)別,例如豌豆莢版默認禁止版本自動更新:

    android {
        defaultConfig {
            buildConfigField "boolean", "AUTO_UPDATES", "true"
        }
        productFlavors {
           wandoujia {
                buildConfigField "boolean", "AUTO_UPDATES", "false"
           }        
        }
    }
    
  2. 多渠道資源文件定制
      客戶端經(jīng)常會和一些應(yīng)用分發(fā)市場合作庆亡,需要在應(yīng)用的啟動界面中加上第三方市場的Logo匾乓,類似這類適配形式還有很多。通常對于不同渠道又谋,我們會區(qū)別不同的資源拼缝。例如我們一款應(yīng)用需要在360發(fā)布括享,而應(yīng)用圖標和歡迎界面要一個360標志的圖或者應(yīng)用名稱和其他渠道不同,那么這個時候就需要按渠道打包對應(yīng)的應(yīng)用圖標和歡迎圖片以及應(yīng)用名稱了了珍促。
      Gradle在構(gòu)建應(yīng)用時,會優(yōu)先使用flavor所屬dataSet中的同名資源剩愧。所以猪叙,在flavor的dataSet中添加同名的字符串資源,以覆蓋默認的資源仁卷。上面我們已經(jīng)有針對360的渠道了穴翩,就是qihu360,我們只需要在app/src/目錄下添加渠道對應(yīng)的文件夾qihu360锦积,然后覆蓋對應(yīng)要覆蓋的內(nèi)容芒帕。下面是定制應(yīng)用圖標的步驟:

  • 添加qihu360文件夾,那么在 app/src/目錄下面就有 main , androidTest , qihu360,test這四個文件夾了丰介。main 目錄是通用正常渠道包目錄背蟆,qihu360是我們需要定制資源的渠道包目錄。如下圖:
    Paste_Image.png
  • 并添加如下應(yīng)用名字符串資源src/qihu360/res/values/strings.xml:
      <resources>    
      <string name="app_name">360MultiChannelBuild</string>
      </resources>
    
    默認的應(yīng)用名字符串資源如下(src/main/res/values/strings.xml):
    <resources>    
      <string name="app_name">MultiChannelBuild</string>
    </resources>
    
    最后運行360版本的app即應(yīng)用名稱顯示成360MultiChannelBuild哮幢。
    通過以上例也可以定制其他資源带膀,包括drawablestyles.xml甚至AndroidManifest.xml也都是可以的橙垢。即可實現(xiàn)不同渠道不同的應(yīng)用顯示垛叨。
  1. 使用第三方SDK
    某些渠道會要求客戶端嵌入第三方SDK來滿足特定的適配需求。問題的難點在于如何只為特定的渠道添加SDK柜某,其他渠道不引入該SDK嗽元。使用flavor可以很好的解決這個問題,下面以為qihu360flavor引入com.qihoo360.union.sdk:union:1.0
    SDK為例進行說明:
android {
    productFlavors {
        qihu360 {
        }
    }
}
...
dependencies {
    //參與編譯但不參與打包
    provided 'com.qihoo360.union.sdk:union:1.0'
    //指定qihu360這個渠道可以打包這個庫
    qihu360Compile 'com.qihoo360.union.sdk:union:1.0'
}

上例添加了名為qihu360的flavor喂击,并且指定編譯和運行時都依賴com.qihoo360.union.sdk:union:1.0剂癌。而其他渠道只是在構(gòu)建的時候依賴該SDK,打包的時候并不會添加它惭等。
接下來珍手,需要在代碼中使用反射技術(shù)判斷應(yīng)用程序是否添加了該SDK,從而決定是否要顯示360 SDK提供的精品應(yīng)用辞做。部分代碼如下:

class MyActivity extends Activity {
    private boolean useQihuSdk;

    @override
    public void onCreate(Bundle savedInstanceState) {
        try {
            Class.forName("com.qihoo360.union.sdk.UnionManager");
            useQihuSdk = true;
        } catch (ClassNotFoundException ignored) {

        }
    }
}

最后打包運行即可生成包含360精品應(yīng)用模塊的渠道包了琳要。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市秤茅,隨后出現(xiàn)的幾起案子稚补,更是在濱河造成了極大的恐慌,老刑警劉巖框喳,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件课幕,死亡現(xiàn)場離奇詭異厦坛,居然都是意外死亡,警方通過查閱死者的電腦和手機乍惊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門杜秸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人润绎,你說我怎么就攤上這事撬碟。” “怎么了莉撇?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵呢蛤,是天一觀的道長。 經(jīng)常有香客問我棍郎,道長其障,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任涂佃,我火速辦了婚禮励翼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辜荠。我一直安慰自己抚笔,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布侨拦。 她就那樣靜靜地躺著殊橙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狱从。 梳的紋絲不亂的頭發(fā)上膨蛮,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音季研,去河邊找鬼敞葛。 笑死,一個胖子當著我的面吹牛与涡,可吹牛的內(nèi)容都是我干的惹谐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼驼卖,長吁一口氣:“原來是場噩夢啊……” “哼氨肌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酌畜,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤怎囚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后桥胞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恳守,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡考婴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了催烘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沥阱。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖伊群,靈堂內(nèi)的尸體忽然破棺而出喳钟,到底是詐尸還是另有隱情,我是刑警寧澤在岂,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蛮寂,受9級特大地震影響蔽午,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酬蹋,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧分瘦,春花似錦拇砰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至象泵,卻和暖如春寞秃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偶惠。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工春寿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人忽孽。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓绑改,卻偏偏與公主長得像,于是被迫代替她去往敵國和親兄一。 傳聞我的和親對象是個殘疾皇子厘线,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 最近在項目中遇到需要實現(xiàn) Apk 多渠道、定制化打包出革, Google 皆的、百度查找了一些資料,成功實現(xiàn)了上述功能蹋盆,在...
    看一季殘花落幕閱讀 2,483評論 1 8
  • 版權(quán)聲明:本文為博主原創(chuàng)文章费薄,未經(jīng)博主允許不得轉(zhuǎn)載硝全。 最近在項目中遇到需要實現(xiàn) Apk 多渠道、定制化打包楞抡, Go...
    牙鍋子閱讀 6,010評論 3 33
  • 目錄一伟众、Python打包及優(yōu)化(美團多渠道打包)二、Gradle打包三召廷、其他打包方案:修改Zip文件的commen...
    守望君閱讀 5,675評論 4 17
  • 1.介紹 如果你正在查閱build.gradle文件的所有可選項凳厢,請點擊這里進行查閱:DSL參考 1.1新構(gòu)建系統(tǒng)...
    Chuckiefan閱讀 12,118評論 8 72
  • 環(huán)境 OSXAndroidStudio 1.0 多渠道設(shè)置 渠道號 以友盟SDK為例,打包多渠道:GooglePl...
    SaiWu閱讀 2,540評論 0 6