1. 程式人生 > >Android多渠道批量打包

Android多渠道批量打包

文件 boolean clas 跟蹤 技術 ref bst 更新 xiaomi

如若感覺排版不舒服,請移步Android多渠道批量打包

1、為什麽要進行多渠道打包?

  安卓應用商店(一個商店也叫做一個渠道,如豌豆莢,360手機助手,應用寶)眾多。大大小小幾百個,每當我們發新版本號時。須要將Androidclient分發到各個應用市場。為了統計這些市場的效果(下載量、活躍數等)。須要有一種方法來唯一標識它們,所以才有了多渠道打包。

2、怎樣統計各個渠道的下載量、活躍數?

  如今有比較成熟的第三方應用幫我們實現統計功能(比方友盟),統計的本質就是收集用戶信息傳輸到後臺,後臺生成報表,幫助我們跟蹤分析並完好app。通過android系統的方法已經能夠獲取到引用版本號號,版本號名稱,系統版本號。機型等各種信息,只有應用商店(渠道)的信息我們是沒有辦法從系統獲取到的。所以我們就人為的在apk裏面加入渠道信息(事實上就用一個字段進行標識。如wandoujia

360yingyongbao),我們僅僅要把這些信息打包到apk文件並將信息傳輸到後臺,後臺依據這個標識,能夠統計各個渠道的下載量了。
多渠道打包僅僅須要關註兩件事情:
1. 將渠道信息寫入apk文件
2. 將apk中的渠道信息傳輸到統計後臺

3、以下我們主要講述兩種多渠道打包方式。

* 3.1、美團Android自己主動化之旅—生成渠道包*

過程例如以下:
1. 下載安裝python環境 Python下載地址;
2. 下載python腳本 AndroidMultiChannelBuildTool
3. 將ChannelUtil.java代碼集成到project裏面,在app啟動時獲取渠道號傳送給後臺(如友盟: AnalyticsConfig.setChannel(ChannelUtil.getChannel(this));

);
4. 在PythonTool/Info/channel.txt中編輯渠道列表。以換行隔開。示比例如以下:

samsungapps
hiapk
anzhi
360cn
xiaomi
myapp
91com
gfan
appchina
nduoa
3gcn
mumayi
10086com
wostore
189store
lenovomm
hicloud
meizu
baidu
googleplay
wandou

5. 打包apk,將apk文件拷貝到PythonTool文件夾下(與py同級),執行(直接雙擊.py文件或者在命令行輸入 python MultiChannelBuildTool.py )py腳本就可以打包完畢。(生成的渠道apk包在output_** 文件夾下)

技術分享

技術分享

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

  1. 通常都是在在AndroidManifest.xml中加入渠道區分標識寫入一個meta標簽:
<meta-data   
     android:name="channel"    
     android:value="${channel}" 
/>
  1. 在app文件夾下在build.gradle中配置productFlavors加入例如以下代碼:
productFlavors {
        qihu360 {} // 360手機助手
        yingyongbao {} // 騰訊應用寶
        wandoujia {} // 豌豆莢
        baidu {} // 百度手機助手
        miui {} // 小米
        flyme {} // 魅族
        lenovo {} // 聯想-樂商店
        oppo {} // Oppo-可可軟件商店
        huawei {} // 華為
        vivo {} // vivo
        hiapk {} // 安卓市場
        sj91 {} // 91手機助手
        sogou {} // 搜狗手機市場
        sohu {} // 搜狐應用中心
        taobao {} // 淘寶手機助手
        gfan {} // 機鋒
        appchina {} // 應用匯
        mumayi {} // 木螞蟻
        wangyi163 {} // 網易應用
        nduoa {} // N多市場
        mm10086 {} // MM商城-中國移動
        wostore {} // WO商店
        youyi {} // 優異
        uc {} // UC+開發平臺
        anzhi {} // 安智市場
        google {} // google play
        amazon {} // 亞馬遜
    }
    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [channel: name]
    }

AndroidStudio的Build -> Generate signed apk打簽名包時就可以選擇設置渠道:
技術分享

  1. 在代碼中獲取渠道信息:
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。

技術分享

4.APP定制–適配渠道包

可參考美團技術文檔之美團Android自己主動化之旅—適配渠道包
1. ApplicationId。版本號號
Android 應用都有自己的包名。包名是設備上每一個應用程序的唯一標識,相同也是在各個下載平臺的唯一標識

就是說,假如你已經使用某個包名來公布應用,就不能再去改變應用的包名,由於這樣做會導致你的應用被視為一個全新的應用。你現有的用戶也不會收到應用的更新通知。
隨著渠道越來越多,不同渠道相應用的要求也不盡相同。有時候我們須要公布不同的版本號,比如 prohd 版本號,支持用戶能夠下載安裝不同的版本號。那麽我們須要設置不同的ApplicationId和相應的版本號號。 同一時候要與 PackageName 解耦合。
- 代碼中引用的 R 類要保持不變;
- 在構建不同版本號的應用時,相應的(引用了 R 的) .java 源文件也不能修改。

那麽我們僅僅須要在productFlavors相應的渠道中指定applicationIdversionCodeversionName,例我們指定GooglePlayapplicationId:

 productFlavors {
        GooglePlay {
            //指定這個渠道的版本號號
            versionCode 2
            versionName "1.2"
            //指定差別於其它渠道的 applicationId
            applicationId "com.liujc.androidtools.hd"
        } // 360手機助手
        yingyongbao {} // 騰訊應用寶
        wandoujia {} // 豌豆莢
        baidu {} // 百度手機助手
        miui {} // 小米
        //其它...
    }
  1. BuildConfig
    Gradle會在generateSources階段為flavor生成一個BuildConfig.java文件。BuildConfig類默認提供了一些常量字段。比方應用的版本號名(VERSION_NAME),應用的包名(PACKAGE_NAME)等。

    更強大的是,開發人員還能夠加入自己定義的一些字段。

    以下的示比如果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 了。

  1. 控制是否自己主動更新
    一般應用在啟動時都會默認檢查client是否有更新,如果有更新就會提示用戶下載。

    可是有些渠道和應用市場不同意這樣的默認行為,所以在適配這些渠道時須要禁止自己主動更新功能。
    解決的思路是提供一個配置字段,應用啟動的時候檢查該字段的值以決定是否開啟自己主動更新功能。使用flavor能夠完美的解決這類問題。甚至能夠在productFlavors相應的渠道號進行差別。比如豌豆莢版默認禁止版本號自己主動更新:

    android {
               defaultConfig {
               buildConfigField "boolean", "AUTO_UPDATES", "true"
               }
              productFlavors {
                 wandoujia {
                     buildConfigField "boolean", "AUTO_UPDATES", "false"
                 }        
              }
        }
  1. 多渠道資源文件處理
      client常常會和一些應用分發市場合作。須要在應用的啟動界面中加上第三方市場的Logo,相似這類適配形式還有非常多。

    通常對於不同渠道。我們會差別不同的資源。比如我們一款應用須要在360公布。而應用圖標和歡迎界面要一個360標誌的圖或者應用名稱和其它渠道不同。那麽這個時候就須要按渠道打包相應的應用圖標和歡迎圖片以及應用名稱了了。
      Gradle在構建應用時。會優先使用flavor所屬dataSet中的同名資源。所以,在flavor的dataSet中加入同名的字符串資源。以覆蓋默認的資源。上面我們已經有針對360的渠道了,就是qihu360,我們僅僅須要在app/src/文件夾下加入渠道相應的文件夾qihu360,然後覆蓋相應要覆蓋的內容。以下是定制應用圖標的步驟:

    • 加入qihu360文件夾,那麽在 app/src/文件夾以下就有 main , androidTest , qihu360,test這四個文件夾了。main 文件夾是通用正常渠道包文件夾,qihu360是我們須要定制資源的渠道包文件夾。例如以下圖:
      技術分享
    • 並加入例如以下應用名字符串資源src/qihu360/res/values/strings.xml:
<resources>    
  <string name="app_name">360MultiChannelBuild</string>
</resources>

默認的應用名字符串資源例如以下(src/main/res/values/strings.xml):

<resources>    
  <string name="app_name">MultiChannelBuild</string>
</resources>

最後執行360版本號的app即應用名稱顯示成360MultiChannelBuild。


通過以上例也能夠定制其它資源,包括drawablestyles.xml甚至AndroidManifest.xml也都是能夠的。

就可以實現不同渠道不同的應用顯示。


5. 使用第三方SDK(來自美團Android自己主動化之旅—適配渠道包)
某些渠道會要求client嵌入第三方SDK來滿足特定的適配需求。

比方360應用市場要求美團團購Androidclient的精品應用模塊使用他們提供的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

而其它渠道僅僅是在構建的時候依賴該SDK,打包的時候並不會加入它。


接下來,須要在代碼中使用反射技術推斷應用程序是否加入了該SDK,從而決定是否要顯示360 SDK提供的精品應用。

部分代碼例如以下:

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精品應用模塊的渠道包了。

Android多渠道批量打包