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


當項目需要有更多的客戶的時候,你就會考慮將apk上架到應用商店了,無奈天朝Android應用商店真的是百家爭鳴,據某地不完全統計已經有900+。若將Apk上架到所有的應用商店是個好主意,但是據統計也就那么十來個應用商店的占有率已經超過95%了,所以我覺得並沒有必要上架所有應用商店。這里就好比Android里面適配機型一個道理,機型無數,但是也就那么幾個品牌占有的絕大多數市場。

話說回來為什么要打渠道包(比如說應用寶要發一個apk,小米應用商店要發一個apk等等),而不是同一個apk放到每一個應用商店呢?主要有下列原因:

1. 不同的應用商店對於apk的要求不同,有的甚至需要一些定制,比如某些應用商店要求在啟動頁加入商店的Logo

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

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

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

 

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


 

在moudle的build.gradle的android元素下,有這么productFlavors這么一個函數,它支持不同“口味”的版本編譯。比如我們需要做一個應用寶的渠道版本,可以添加下列代碼:

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

隨后在AndroidManifest.xml的配置友盟渠道號的地方改成:

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

productFlavors中的manifestPlaceholder類似於給AndroidManifest文件定義了一個變量,上述例子中改變量名字就加UMENT_CHANNEL,值為字符串YingYongBao,這樣子改渠道打包出來的apk即可以發布到應用寶市場上了。同時你在友盟的后台統計模塊控制台中,也可以看到一個叫做“YingYongBao”的渠道來源,可以跟蹤該渠道的用戶使用數據。這樣我們要解決的第2個問題OK了。

 

productFlavors中的buildConfigField是在等於在預編譯期間創建了一個變量叫做CHANNEL,類型是字符串類型,值是字符串“YingYongBao”。

當我們寫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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM