Android:Gradle 通用配置

完整配置的Guthub地址:https://github.com/WangFion/mvp-mode

一、什么是 Gradle


??關(guān)于 Gradle 是什么,這里我就不做過(guò)多的贅述了塘装,打開(kāi)度娘一搜一大片顷啼,感興趣的童鞋可以自行學(xué)習(xí)哈锌俱!這里我就簡(jiǎn)單描述一下:
??Gradle 是一個(gè)基于 Apache Ant 和 Apache Maven 概念的項(xiàng)目自動(dòng)化構(gòu)建工具毫胜。它使用一種基于 Groovy 的特定領(lǐng)域語(yǔ)言來(lái)聲明項(xiàng)目設(shè)置晰甚,而不是傳統(tǒng)的 XML降瞳。Gradle 就是工程的管理嘱支,幫我們做了依賴(lài)、打包挣饥、部署除师、發(fā)布、各種渠道的差異管理等工作扔枫。
??這里你只需要己住一點(diǎn):Gradle 是一個(gè)自動(dòng)化構(gòu)建工具汛聚,這就ok了。


二短荐、AS 中的 Gradle 版本


??在 Android Studio 中使用 Gradle 有三個(gè)版本需要注意:AS 版本倚舀、Gradle 插件版本叹哭、Gradle 版本。

1痕貌、AS版本

AS-Version.png

2风罩、Gradle 插件版本(項(xiàng)目根目錄的 build.gradle

classpath 'com.android.tools.build:gradle:3.6.3'

3、Gradle 版本(項(xiàng)目根目錄的 /gradle/wrapper/gradle-wrapper.properties

#Sat May 09 20:18:45 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

1舵稠、其中 AS 的版本和 Gradle 插件的版本是有對(duì)應(yīng)關(guān)系的超升,Gradle 版本根據(jù)項(xiàng)目而定,建議都保持最新版本哺徊。
2室琢、有新版本,如果更新之后編譯不過(guò)并且很難解決落追,亦可保持原編譯通過(guò)版本不變盈滴。
3、個(gè)人建議有新版本就及時(shí)更新轿钠,不要累積很多版本后一次更新巢钓;否則到必須更新的時(shí)候再去更新,相信我你會(huì)痛苦萬(wàn)分的谣膳。


三竿报、Project 的 Gradle 通用配置


??Project 的 Gradle 配置的是項(xiàng)目統(tǒng)一化、公用化的一些信息继谚,目的是為了保證公共的信息在每個(gè) Module 中都是一致的,而每個(gè) Module 只需要去配置自己的一些差異化的信息阵幸。
??Project 的 Gradle 的配置文件是根目錄下面的 build.gradle花履,這里面主要配置遠(yuǎn)程倉(cāng)庫(kù)、插件挚赊、項(xiàng)目版本信息诡壁、公共 lib 等。

1荠割、遠(yuǎn)程倉(cāng)庫(kù)配置

repositories {
    // wf-update: 2020/5/9 16:57 添加aliyun鏡像妹卿,優(yōu)化jcenter和google訪(fǎng)問(wèn)
    maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
    maven { url 'https://maven.aliyun.com/repository/jcenter' }
    maven { url 'https://maven.aliyun.com/repository/google' }
    google()
    jcenter()
}

往往在我們項(xiàng)目開(kāi)發(fā)的過(guò)程中都會(huì)集成很多 Google 和第三方的開(kāi)源庫(kù),而受?chē)?guó)內(nèi)環(huán)境的影響使用 google() 和 jcenter() 下載這些庫(kù)往往不盡人意蔑鹦,所以這里推薦配置國(guó)內(nèi)的鏡像地址(當(dāng)然不止我上面列舉的這些)夺克,會(huì)有意想不到的效果哦。注意這里需要同時(shí)配置 buildscriptallprojects 方法塊嚎朽。

2铺纽、插件配置

dependencies {
    classpath 'com.android.tools.build:gradle:3.6.3'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

注意這里的 dependencies 配置的是項(xiàng)目編譯所用到的插件,一定要區(qū)別于 Module 里面的 dependencies 哟忍,注意閱讀 NOTE 的英文說(shuō)明狡门。上例中我們配置了一個(gè) Gradle 插件和 Kotlin 插件陷寝。

3、項(xiàng)目版本信息

/**
 * 應(yīng)用版本相關(guān)配置信息
 */
ext {
    applicationId      = "com.wf.mvp.mode"
    apkName            = "MvpMode"
    versionCode        = 1
    versionName        = "v1.0"
    compileSdkVersion  = 29
    buildToolsVersion  = "29.0.2"
    minSdkVersion      = 19
    targetSdkVersion   = 29
}

這里配置的是我們項(xiàng)目的包名其馏、版本號(hào)凤跑、sdk 版本、編譯版本等信息叛复,當(dāng)然了這里我們只是定義仔引,具體的使用是在每個(gè) Module 里面通過(guò) rootProject.applicationId 的形式來(lái)調(diào)用,項(xiàng)目的每個(gè) Module 都通過(guò)這種形式來(lái)配置版本信息后致扯,后續(xù)版本調(diào)整我們就只需要修改這里就 ok 了肤寝。

4、公共 lib 配置

/**
 * Module通用lib
 */
ext {
    lib_kotlin            = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    lib_appcompat         = 'androidx.appcompat:appcompat:1.1.0'
    lib_core_ktx          = 'androidx.core:core-ktx:1.2.0'
    lib_constraintlayout  = 'androidx.constraintlayout:constraintlayout:1.1.3'
    lib_junit             = 'junit:junit:4.13'
    lib_ext_junit         = 'androidx.test.ext:junit:1.1.1'
    lib_espresso_core     = 'androidx.test.espresso:espresso-core:3.2.0'
}

同上面的版本信息一樣抖僵,公用的 lib 庫(kù)我們也可以定義在這里鲤看,子 Module 亦是通過(guò) rootProject.lib_appcompat 的形式來(lái)調(diào)用,當(dāng)然了和上面的版本信息寫(xiě)在一個(gè) ext 方法塊里面也可以耍群,為了區(qū)分我們這里是分開(kāi)寫(xiě)的义桂。


四、Module 的 Gradle 通用配置


??這里 Module 的 Gradle 主要是用來(lái)配置各個(gè) Module 的差異化信息蹈垢,公共的信息均調(diào)用 Project 的 Gradle 里面定義好的慷吊。
??Module 的 Gradle 的配置文件是相應(yīng)的 Module 目錄下面的 build.gradle,這里面主要配置插件引用曹抬、版本信息溉瓶、簽名信息、編譯信息谤民、渠道信息堰酿、APK格式化輸出、第三方框架及 lib 引用 等张足。

1触创、插件引用

// path -> app/build.gradle
apply plugin: 'com.android.application'
// apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

??第一行配置此 Module 為 Application 還是 Library,為 Application 時(shí)可以單獨(dú)運(yùn)行为牍。這里在組件化開(kāi)發(fā)中尤為重要哼绑,可以通過(guò)參數(shù)來(lái)配置此 Module 為 Application 還是 Library。
??后面兩行為配置的 Kotlin 支持插件碉咆,當(dāng)然了這里還可以配置一些其他需要用到的插件抖韩。

2、版本信息

// path -> app/build.gradle
// --------------- wf-update: 2020/5/9 17:53 版本配置信息 ---------------
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion rootProject.buildToolsVersion

defaultConfig {
    applicationId rootProject.applicationId
    minSdkVersion rootProject.minSdkVersion
    targetSdkVersion rootProject.targetSdkVersion
    versionCode rootProject.versionCode
    versionName rootProject.versionName

    buildConfigField("String", "DEFAULT_CONFIG", "\"default\"")

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

??這里配置的是應(yīng)用版本相關(guān)的信息吟逝,此信息均定義在 Project 的 Gradle 里面帽蝶,故這里均引用的 Project 的 Gradle 里面定義的信息。所有的 Module 版本信息都應(yīng)參照這里配置來(lái)保證整個(gè)工程的版本一致。

buildConfigField 定義的字段可以在代碼中通過(guò) BuildConfig.DEFAULT_CONFIG 的形式來(lái)調(diào)用励稳,這在后面講到的版本和渠道里面會(huì)非常有用佃乘。注意這里定義的字符串需要加上雙引號(hào)

3驹尼、簽名信息

// path -> app/build.gradle
// --------------- wf-update: 2020/5/9 17:55 簽名配置信息 ---------------
signingConfigs {
    debug {

    }
    release {
        keyAlias 'mvp'
        keyPassword 'mvp123'
        storeFile file('../sign/mvp.jks')
        storePassword 'mvp123'
    }
}

??簽名信息配置沒(méi)什么特別的趣避,簽名文件可以使用 AS 或者其他簽名文件生成工具均可。具體的步驟這里不再贅述新翎,可以自行百度程帕。

4、編譯信息

// path -> app/build.gradle
// --------------- wf-update: 2020/5/20 19:04 版本編譯信息 ---------------
buildTypes {
    debug {
        buildConfigField("String", "BUILD_TYPES", "\"build_debug\"")
    }
    release {
        buildConfigField("String", "BUILD_TYPES", "\"build_release\"")
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

??編譯信息配置用來(lái)配置我們編譯的版本是 debug 還是 release地啰,不同的版本我們可以配置不同的信息以及變量等愁拭。這里我們?cè)?release 版本中配置了上面定義的簽名信息,而 dubug 沒(méi)有亏吝。當(dāng)我們使用 assemble 命令編譯時(shí)會(huì)在 app/build/outputs/apk 目錄下同時(shí)輸出 debug 和 release 版本的apk岭埠,而單獨(dú)使用 assembleDebug 或者 assembleRelease 只會(huì)輸出對(duì)應(yīng)的一個(gè)版本的apk。

5蔚鸥、渠道信息

// path -> app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wf.mvp.mode"
    android:sharedUserId="${SHARED_USER_ID}">

    <application ......>
        ......
        <meta-data
            android:name="CHANNEL_INFO"
            android:value="${CHANNEL_VALUE}" />
    </application>

</manifest>
// path -> app/build.gradle
// --------------- wf-update: 2020/5/19 20:36 渠道配置信息 ---------------
flavorDimensions "company", "channel"
productFlavors {
    huawei {
        dimension "company"
        buildConfigField("String", "FLAVOR_COMPANY", "\"huawei\"")
        manifestPlaceholders = [
                SHARED_USER_ID: "android.uid.huawei",
                CHANNEL_VALUE : "huawei"
        ]
    }
    xiaomi {
        dimension "company"
        buildConfigField("String", "FLAVOR_COMPANY", "\"xiaomi\"")
        manifestPlaceholders = [
                SHARED_USER_ID: "android.uid.xiaomi",
                CHANNEL_VALUE : "xiaomi"
        ]
    }

    phone {
        dimension "channel"
        buildConfigField("String", "FLAVOR_COMPANY", "\"phone\"")
        buildConfigField("String", "FLAVOR_CHANNEL", "\"phone\"")
        manifestPlaceholders = [
                SHARED_USER_ID: "android.uid.phone",
                CHANNEL_VALUE : "phone"
        ]
    }
    tv {
        dimension "channel"
        buildConfigField("String", "FLAVOR_COMPANY", "\"tv\"")
        buildConfigField("String", "FLAVOR_CHANNEL", "\"tv\"")
        manifestPlaceholders = [
                SHARED_USER_ID: "android.uid.tv",
                CHANNEL_VALUE : "tv"
        ]
    }
}

??渠道配置是針對(duì)不同的渠道而進(jìn)行的差異化配置惜论。這里有以下幾點(diǎn)需要說(shuō)明:

  • 多渠道維度(flavorDimensions): AS 3.0之后出現(xiàn)的,至少需要定義一個(gè)維度止喷。舉個(gè)栗子:A 廠(chǎng)商生產(chǎn)了 C馆类、D 兩個(gè)產(chǎn)品,B 廠(chǎng)商也生產(chǎn)了 C弹谁、D 兩個(gè)產(chǎn)品乾巧,這里就需要用到二維渠道了,就會(huì)有 AC预愤、AD卧抗、BC、BD 四個(gè)產(chǎn)品鳖粟。
  • 渠道維度順序:渠道維度的定義是有先后順序的,如果渠道里面有相同的配置信息拙绊,先定義的維度會(huì)覆蓋后定義的維度向图,如上例中的 FLAVOR_COMPANY、SHARED_USER_ID 和 CHANNEL_VALUE 的值始終都會(huì)是 company 維度下的 huawei 或者 xiaomi标沪,不可能為 channel 維度下的 phone 或者 tv榄攀。可以去 app/build/generated/source/buildConfig 下的 BuildConfig.java 文件中驗(yàn)證金句。

6檩赢、APK格式化輸出

// path -> app/build.gradle
// --------------- wf-update: 2020/5/9 17:58 APK格式化輸出配置 ---------------
applicationVariants.all { variant ->
    variant.outputs.all {
        def fileName
        def formattedDate = new Date().format("yyyy-MM-dd-HHmmss")
        if (variant.buildType.name == 'release') {
            fileName = "${rootProject.apkName}_${variant.mergedFlavor.versionName}_${formattedDate}_release.apk"
        } else {
            fileName = "${rootProject.apkName}_${variant.mergedFlavor.versionName}_${formattedDate}_debug.apk"
        }
        outputFileName = fileName
    }
}

??這里也沒(méi)有什么好講的,自行根據(jù)項(xiàng)目來(lái)定義 apk 的輸出名稱(chēng)违寞,默認(rèn)的輸出路徑是 app/build/outputs/apk贞瞒,也可以修改此輸出路徑偶房,但是修改輸出路徑后,當(dāng)我們?cè)谑褂?AS run 來(lái)調(diào)試應(yīng)用的時(shí)候可能會(huì)報(bào)找不到 xxx.apk 的錯(cuò)誤军浆,所以建議不要修改棕洋。

7、第三方框架及 lib 引用

// path -> app/build.gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation rootProject.lib_kotlin
    implementation rootProject.lib_appcompat
    implementation rootProject.lib_core_ktx
    implementation rootProject.lib_constraintlayout
    testImplementation rootProject.lib_junit
    androidTestImplementation rootProject.lib_ext_junit
    androidTestImplementation rootProject.lib_espresso_core

    //引用其他 Module
    implementation project(path: ':mvp-kotlin')
    implementation project(path: ':mvp-java')

    //內(nèi)存泄漏
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
}

??這里主要用來(lái)引用需要的外部庫(kù)文件和 Library Module乒融,通用的庫(kù)我們還是通過(guò) rootProject.lib_appcompat 的形式來(lái)引用我們?cè)?Project 里面定義好的掰盘,保證通用庫(kù)版本統(tǒng)一。注意區(qū)別這里的 dependencies 和我們上面講到的 Project 的 build.gradle 里面的 dependencies赞季。


總結(jié)


??到這里愧捕,我們基礎(chǔ)的、也是大多數(shù)項(xiàng)目必須的通用配置就講完了申钩,任何一個(gè)新項(xiàng)目把這套配置拿過(guò)去基本上都能滿(mǎn)足需求次绘。當(dāng)然了 Gradle 用法遠(yuǎn)不止這些,像是源文件路徑配置典蜕、ndk 配置断盛、編譯檢測(cè)等等,感興趣的童鞋可以自己去研究愉舔。以上就是本篇文章的全部?jī)?nèi)容钢猛,如有錯(cuò)誤的地方或者更好的建議歡迎在下方留言討論,謝謝轩缤!

完整配置的Guthub地址:https://github.com/WangFion/mvp-mode

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載命迈,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末火的,一起剝皮案震驚了整個(gè)濱河市壶愤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌馏鹤,老刑警劉巖征椒,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異湃累,居然都是意外死亡勃救,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)治力,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蒙秒,“玉大人,你說(shuō)我怎么就攤上這事宵统≡谓玻” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)瓢省。 經(jīng)常有香客問(wèn)我弄息,道長(zhǎng),這世上最難降的妖魔是什么净捅? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任疑枯,我火速辦了婚禮,結(jié)果婚禮上蛔六,老公的妹妹穿的比我還像新娘荆永。我一直安慰自己,他們只是感情好国章,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布具钥。 她就那樣靜靜地躺著,像睡著了一般液兽。 火紅的嫁衣襯著肌膚如雪骂删。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天四啰,我揣著相機(jī)與錄音宁玫,去河邊找鬼。 笑死柑晒,一個(gè)胖子當(dāng)著我的面吹牛欧瘪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匙赞,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼佛掖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了涌庭?” 一聲冷哼從身側(cè)響起芥被,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坐榆,沒(méi)想到半個(gè)月后拴魄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡席镀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年羹铅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愉昆。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖麻蹋,靈堂內(nèi)的尸體忽然破棺而出跛溉,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布芳室,位于F島的核電站专肪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏堪侯。R本人自食惡果不足惜嚎尤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伍宦。 院中可真熱鬧芽死,春花似錦、人聲如沸次洼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卖毁。三九已至揖曾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亥啦,已是汗流浹背炭剪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翔脱,地道東北人奴拦。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像碍侦,于是被迫代替她去往敵國(guó)和親粱坤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344