Android一鍵多渠道分發打包實戰和解析

當項目須要有更多的客戶的時候,你就會考慮將apk上架到應用商店了,無奈天朝Android應用商店真的是百家爭鳴,據某地不徹底統計已經有900+。若將Apk上架到全部的應用商店是個好主意,可是據統計也就那麼十來個應用商店的佔有率已經超過95%了,因此我以爲並無必要上架全部應用商店。這裏就比如Android裏面適配機型一個道理,機型無數,可是也就那麼幾個品牌佔有的絕大多數市場。html

話說回來爲何要打渠道包(好比說應用寶要發一個apk,小米應用商店要發一個apk等等),而不是同一個apk放到每個應用商店呢?主要有下列緣由:java

1. 不一樣的應用商店對於apk的要求不一樣,有的甚至須要一些定製,好比某些應用商店要求在啓動頁加入商店的Logoandroid

2. 爲了跟蹤每家應用商店的用戶數等等統計數據app

幸運的是gradle天生就提供了打多渠道包的功能,這裏咱們主要解決下列問題:函數

  • 如何打多個渠道的包
  • 如何支持友盟統計
  • 如何在代碼中根據不一樣渠道作執行不一樣的代碼塊,即渠道定製
  • 如何支持多包名打包
  • 一種對於BuildConfig的更有意思的用法(彩蛋)

 

修改build.gradle和預編譯BuildConfig類解析gradle


 

在moudle的build.gradle的android元素下,有這麼productFlavors這麼一個函數,它支持不一樣「口味」的版本編譯。好比咱們須要作一個應用寶的渠道版本,能夠添加下列代碼:ui

android {
    productFlavors {
        YingYongBao {
            manifestPlaceholders = [UMENG_CHANNEL:"YingYongBao"]
            buildConfigField "String", "CHANNEL", "\"YingYongBao\""
        }
}

隨後在AndroidManifest.xml的配置友盟渠道號的地方改爲:spa

<meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL}" />

productFlavors中的manifestPlaceholder相似於給AndroidManifest文件定義了一個變量,上述例子中改變量名字就加UMENT_CHANNEL,值爲字符串YingYongBao,這樣子改渠道打包出來的apk便可以發佈到應用寶市場上了。同時你在友盟的後臺統計模塊控制檯中,也能夠看到一個叫作「YingYongBao」的渠道來源,能夠跟蹤該渠道的用戶使用數據。這樣咱們要解決的第2個問題OK了。.net

 

productFlavors中的buildConfigField是在等於在預編譯期間建立了一個變量叫作CHANNEL,類型是字符串類型,值是字符串「YingYongBao」。debug

當咱們寫C/C++代碼的時候一般會寫預編譯宏變量,能夠控制代碼中在不一樣編譯條件下的執行分支。好比:

#ifdef _MACRO_YING_YONG_BAO
{
// code for yingyongbao
}
#else
{
// code for others
}
#endif

當須要執行應用寶那部分代碼的時候則編譯時打開宏_MACRO_YING_YONG_BAO。而Android Studio也提供了相似的機制,它在預編譯階段生成了一個叫作BuildConfig.java的類,它位於:

當咱們預編譯時會自動生成這麼一個類,按照上述編譯應用寶渠道的操做中,咱們看下這個BuildConfig.java是什麼內容:

這裏發現有一個叫作CHANNEL的String常量,並且值是「YingYongBao」,因此想到那麼這裏爲了讓不一樣渠道執行不一樣的代碼,咱們因而能夠在代碼中這樣子寫:

if (BuildConfig.CHANNEL.equals("YingYongBao")) {
// code block for yingyongbao    
} else if (BuildConfig.CHANNEL.equals("360") {
// code block for 360
} else {
// default code
}

這裏須要注意的一點,經過buildConfigField定義的變量中,若是是String類型的話,必需要在值裏面寫上轉義符號\",或者寫成:

buildConfigField "String", "CHANNEL", ‘"YingYongBao"’

不然的話預編譯器會認爲YingYongBao不是一個值而是另外一個變量,從而報錯:

 

到此,第3個問題也解決了!

 

 

在Android Studio中一鍵打包


 

到如今尚未說如何打包的事情,這點很簡單,只要打開Android Studio的gradle面板,刷新task列表,會發現不少task,只要雙擊下assembleRelease這個task便可。稍等一段時間,Android Studio自動幫你生成全部的渠道的Apk。

生成的全部apk在這裏:

這裏有兩個注意點:

  1. 執行打包前,最好先執行下clean那個task
  2. build那個task也能夠打全部渠道的包,可是比較慢,由於它同時也打出來debug包,而assembleRelease只打release包,理論上減小一半時間

問題1解決

 

多包名支持


 

在build.gradle中是用applicationId來表述包名的,在productFlavors中是能夠嵌入applicationId的定義,好比咱們在Beta這樣的渠道中想要打出一個com.qianmi.xxx.beta的包名的apk,能夠這麼寫:

productFlavors {
        Beta {
            manifestPlaceholders = [UMENG_CHANNEL:"Beta"]
            buildConfigField "String", "CHANNEL", "\"Beta\""
            applicationId "com.qianmi.xxx.beta"
        }

}

 

問題4解決

 

BuildConfig的一種有意思的用法(彩蛋)


咱們知道發佈出去的apk都是帶有簽名的,而從Android Studio等IDE中直接run到手機上的是沒有簽名的,可是兩個手機,一臺裝了簽名的apk一臺是直接run上去的,你能區分出來嗎(實際是看不出來的)?

若是咱們能動態的區分出來,同時對於直接從IDE運行出來的Apk中在app的某個界面(好比關於界面)有下列標誌多好?

而在正式發佈出來的版本中沒有「開發版本」這個字串。

 

首先咱們在build.gradle中的android元素下的buildTypes函數中加入:

buildTypes {
        release {
            minifyEnabled true
            zipAlignEnabled true
            shrinkResources true
            signingConfig signingConfigs.release
            proguardFiles 'proguard-rules.pro'
        }

        debug {
            minifyEnabled false
            zipAlignEnabled true
            shrinkResources true
            buildConfigField "String", "CHANNEL", "\"dev\""
        }

    }

這裏有一個release和一個debug。當你經過上述講解中的gradle task中打包時是release,打包時讀取具體的productFlavors。而若是你是直接從IDE運行出來調試的話,會檢查buildTypes中debug這個地方,這裏咱們一樣把CHANNEL這個常量給定義出來了,值是dev。

因而咱們再在關於界面,寫上下列語句便可:

if (BuildConfig.CHANNEL.equals("dev")) {
            tvVersion.setText("v" + AppUtils.getVersionName(getApplicationContext()) + " " + getString(R.string.dev_version));
        } else {
            tvVersion.setText("v" + AppUtils.getVersionName(getApplicationContext()));

        }

 

題外話


 

到此爲止,多渠道打包問題已經解決。可是打包的時候發現若是渠道越多實際上打包的時間是越慢的,由於Android Studio在爲每一個渠道一個個的生成apk,因此咱們這裏提供的方式僅僅適用於渠道比較少的狀況下。若是你真的想要在900個以上的應用市場發佈大家的apk,那麼顯然這種方式就不行了。這裏提供兩個解決方法。

一個是對同一個base的apk進行修改的方式,能夠參考美團技術團隊的博客:

http://tech.meituan.com/mt-apk-packaging.html

或者

http://blog.csdn.net/luck_apple/article/details/8634572?utm_source=tuicool&utm_medium=referral

第二個是試用一些廠商的支持多渠道打包的軟件,好比360的加固寶:

http://jiagu.360.cn/

 

文末附上一家統計公司提供的國內應用市場佔有率的報告:

轉載請註明出處: http://www.cnblogs.com/soaringEveryday/p/5368540.html

相關文章
相關標籤/搜索