[06]——使用gradle打包多個(gè)變體(variant)

轉(zhuǎn)載請(qǐng)標(biāo)明原文地址:http://www.reibang.com/p/843055bf6edd

重要更新

  1. 現(xiàn)在新建變體還需要在 defaultConfig 下加入 flavorDimensions "versionCode"
  2. 我寫了一個(gè)腳本可以快速的創(chuàng)建變體的sourceSet预烙,項(xiàng)目地址:junerver/flavor_cli

使用方法:將該腳本復(fù)制到項(xiàng)目根目錄下(與app目錄同級(jí))喜每,然后運(yùn)行指令:python3 flavor_variant.py埂软,后續(xù)按照提示輸入即可蛛淋,因?yàn)槭枪┳约洪_發(fā)快速使用的挟秤,所有必然有bug與一些嚴(yán)格匹配的要求,歡迎提PR较锡!


Gradle

背景:剛剛接手的項(xiàng)目中包含3個(gè)客戶端app(兩個(gè)eclipse工程月杉、一個(gè)AS工程),同時(shí)這個(gè)項(xiàng)目根據(jù)不同用戶的制定還有兩個(gè)衍生版本钩杰。原來的開發(fā)人員將項(xiàng)目復(fù)制后修改纫塌,在我接手時(shí)一共存在著9個(gè)工程文件。

當(dāng)我看到這個(gè)項(xiàng)目的時(shí)候近乎崩潰讲弄,因?yàn)檫@意味著每修改一個(gè)端的內(nèi)容還要記著同步到其他的兩個(gè)端中措左。查看后發(fā)現(xiàn),衍生版本中大量的文件是重復(fù)的避除,只是部分比如資源文件怎披、后臺(tái)接口地址等是不同的。我便開始思考瓶摆,如何通過一個(gè)Android Studio工程同時(shí)實(shí)現(xiàn)修改這三個(gè)版本凉逛。

于是便想到了曾看過stormzhang寫過的ANDROID STUDIO系列教程六--GRADLE多渠道打包,這篇文章中簡(jiǎn)單描述了如何使用gradle進(jìn)行多渠道打包(使用占位符替換AndroidManifest文件中友盟統(tǒng)計(jì)的UMENG_CHANNEL的值)群井。

這給了我一定的思路状飞,通過查閱資料,確定了可以使用gradle打包出不同變體(不同applicationId书斜、不同資源文件诬辈、不同APP名稱與圖標(biāo)、不同Java文件)荐吉。

長(zhǎng)篇講解可以查看文章末尾的參考閱讀焙糟,本文只介紹如何實(shí)現(xiàn)。


1 配置不同變體的屬性(簽名样屠、applicationId)

由于項(xiàng)目中每個(gè)客戶端都相當(dāng)于存在三個(gè)版本穿撮,使用不同的簽名文件,因此需要首先實(shí)現(xiàn)的就是對(duì)不同的變體配置不同的簽名痪欲!

配置簽名文件

如上圖所示悦穿,選擇app module,選擇Signing選項(xiàng)卡勤揩,首先配置好了這三個(gè)變體版本的簽名文件。

配置變體Flavors

在Flavors選項(xiàng)卡中秘蛔,新建我們的變體(variant)陨亡,并對(duì)變體進(jìn)行配置傍衡!所有的Flavor都會(huì)復(fù)寫defaultConfig中的屬性,所以可以看到我并沒有填寫其中的一些屬性负蠕。在這里還可以對(duì)不同的變體設(shè)置不同的applicationId(重要蛙埂!這與極光推送等第三方SDK有關(guān))。

創(chuàng)建完畢后同步項(xiàng)目遮糖,會(huì)發(fā)現(xiàn)app moudle下的build.gradle文件內(nèi)容也發(fā)生了變化绣的,如下圖所示:


Paste_Image.png

如果你可以熟練的使用gradle也可以選擇不使用AS提供的UI界面,直接編寫gradle文件欲账。

2 新建不同變體的sourceSet

在修改完變體的配置文件后屡江,我們還需要再項(xiàng)目的src文件夾下新建以我們的Flavor名稱命名的文件夾,并在這些文件夾下新建如main中相同的目錄結(jié)構(gòu)赛不。


目錄結(jié)構(gòu)

我們正常編寫項(xiàng)目都是寫在main這個(gè)sourceSet下的惩嘉,但是如果我們的項(xiàng)目的變體有不同的資源文件、Java文件時(shí)踢故,我們就需要使用不同的sourceSet來區(qū)別開文黎。

需要注意的是,如果是資源文件殿较,F(xiàn)lavor下的資源文件會(huì)與main中的合并耸峭,如果存在重復(fù),則Flavor中優(yōu)先級(jí)高于main中淋纲。我們可以將不同變體中共用的資源存放在main中劳闹,只將不同的內(nèi)容存放在flavor的sourceSet中。

如果不同變體有內(nèi)容不同的Java文件則要注意帚戳,需要將這個(gè) Java 文件放置到每個(gè) flavor 的 sourceSet 文件夾下玷或,main中不可以有這個(gè)Java文件,如果main中也存在此文件片任,編譯時(shí)會(huì)提示文件重復(fù)偏友。比如說有兩個(gè)變體,有著不同的 MainActivity.java对供,那么 main 中就不能有這個(gè)文件了位他。需要把這個(gè) Java 文件放到各個(gè) flavor 的 sourceSet 下,同時(shí)這個(gè) Java 文件在 sourceSet 中要按照 main 中的包結(jié)構(gòu)保存产场。

3 AndroidManifest占位符

由于不同的項(xiàng)目有不同的名稱鹅髓、圖標(biāo),這一點(diǎn)我們可以通過類似上一步的方法京景,在不同的sourceSet中配置string.xml中的app_name屬性窿冯,與drawable文件夾中的ic_launcher。但是這樣有些麻煩确徙,當(dāng)我們的變體版本多了得手就需要不斷的重復(fù)這一動(dòng)作醒串,所以我使用的是在AndroidManifest文件中使用占位符然后在flavor中直接配置的方法执桌。這樣做的好處是,如果以后圖標(biāo)變更只需要到main中找到該文件然后替換即可芜赌,而不用去一個(gè)個(gè)找sourceSet仰挣。

首先將所有圖標(biāo)文件放到main中,然后在 AndroidManifest中使用¥{NAME}格式的占位符缠沈,最后在flavor中使用manifestPlaceholders =[NAME1:VALUE1,NAME2:VALUE2]替換占位符中的內(nèi)容膘壶。

AndroidManifest占位符

在項(xiàng)目中,每個(gè)衍生版本都有自己的極光推送APPKEY屬性洲愤,這也可以是用占位符這一方法來處理颓芭,最終的flavors如下圖所示:

gradle文件

4 調(diào)試不同版本

現(xiàn)在我們擁有了三個(gè)不同的變體,但是我們調(diào)試的時(shí)候如何選擇對(duì)應(yīng)的程序來調(diào)試呢禽篱?

方式一:


方式一

方式二:


方式二

在選擇好要調(diào)試的變體后畜伐,會(huì)發(fā)現(xiàn)對(duì)應(yīng)的 sourceSet 文件夾變成了我們工程文件夾的央視:

選擇需要調(diào)試的變體

可以看到我們一共有6個(gè)可選變體,這是怎么回事呢躺率?我們明明只設(shè)置了3個(gè)flavor玛界。

這時(shí)就需要介紹buildTypes了,再次回到項(xiàng)目配置頁面如下圖所示:

buildTypes

可以看到有兩個(gè)build type悼吱,這其中可以配置構(gòu)建的一些選項(xiàng)慎框,這里就不做過多介紹了。

我們的總變體數(shù)量等于 (build type數(shù)量)*(flavor數(shù)量)后添,這就是為什么一共有六個(gè)可選的variant笨枯。

最后獻(xiàn)上一個(gè)release的buildType配置

release {
    minifyEnabled true
    shrinkResources true       //移除無用資源
    debuggable false
    zipAlignEnabled true        //Zipalign優(yōu)化
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    signingConfig signingConfigs.uerbT
    // 自定義輸出配置
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                // 輸出apk名稱為UerbT_v1.0_2016-12-01_uerbt.apk
                def fileName = "UerbT_v${variant.versionName}_${releaseTime()}_${variant.flavorName}.apk"
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
        //過濾掉unaligned的包
        variant.assemble.doLast {
            variant.outputs.each { output ->
                println "-----------------------------------------"
                println "aligned " + output.outputFile
                println "unaligned " + output.packageApplication.outputFile
                File unaligned = output.packageApplication.outputFile;
                File aligned = output.outputFile
                if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
                    println "deleting " + unaligned.getName()
                    unaligned.delete()
                }
            }
        }
    }
}

releaseTime() 函數(shù)如下:

def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

參考閱讀:
重要-Gradle for Android 第四篇( 構(gòu)建變體 )
重要 - 使用gradle構(gòu)建不同特性的app
gradle配置詳解
知乎問答-如何使用gradle構(gòu)建不同的app
android studio gradle 多版本多apk打包
使用Gradle自動(dòng)化構(gòu)建多類型apk包
外包采用Gradle生成多套app打包
ANDROID STUDIO系列教程六--GRADLE多渠道打包
Android Studio中Gradle使用詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市遇西,隨后出現(xiàn)的幾起案子馅精,更是在濱河造成了極大的恐慌,老刑警劉巖粱檀,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洲敢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡茄蚯,警方通過查閱死者的電腦和手機(jī)压彭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渗常,“玉大人壮不,你說我怎么就攤上這事≈宓猓” “怎么了询一?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我健蕊,道長(zhǎng)缓醋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任绊诲,我火速辦了婚禮,結(jié)果婚禮上褪贵,老公的妹妹穿的比我還像新娘掂之。我一直安慰自己,他們只是感情好脆丁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布世舰。 她就那樣靜靜地躺著,像睡著了一般槽卫。 火紅的嫁衣襯著肌膚如雪跟压。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天歼培,我揣著相機(jī)與錄音震蒋,去河邊找鬼。 笑死躲庄,一個(gè)胖子當(dāng)著我的面吹牛查剖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播噪窘,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼笋庄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了倔监?” 一聲冷哼從身側(cè)響起直砂,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浩习,沒想到半個(gè)月后静暂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘦锹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年籍嘹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弯院。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辱士,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出听绳,到底是詐尸還是另有隱情颂碘,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站头岔,受9級(jí)特大地震影響塔拳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜峡竣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一靠抑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧适掰,春花似錦颂碧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至费就,卻和暖如春诉瓦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背力细。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工睬澡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眠蚂。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓猴贰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親河狐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子米绕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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