與Gradle的那些年

既然要學(xué)習(xí)Gradle献烦,首先要知道它是什么础拨,它又能干什么,以及怎么使用它拔稳。

Gradle是什么?

Gradle 是以Groovy為基礎(chǔ),面向java應(yīng)用锹雏,基于DSL語法的自動化構(gòu)建工具巴比。
是google引入,替換ant和maven的新工具礁遵,其依賴兼容maven和ivy轻绞。

Gradle能干什么?

1.更容易重用資源和代碼;
2.可以更容易創(chuàng)建不同的版本的程序榛丢,多個類型的apk包铲球;
3.更容易配置,擴(kuò)展;
4.更好的IDE集成晰赞;

Android Studio中的android項(xiàng)目通常至少包含兩個build.gradle文件,一個是project范圍的选侨,另一個是module范圍的掖鱼,由于一個project可以有多個module,所以每個module下都會對應(yīng)一個build.gradle援制。

project->build.gradle

project下的build.gradle是整個project的配置戏挡,主要配置gradle 版本及 全局依賴倉庫、庫或者其他全部參數(shù)晨仑。android studio 現(xiàn)在重要倉庫采用jcenter(),之前版本放在mavenCentral褐墅。另外有時還沒有加入jcenter()倉庫的第三方庫,也需要在這里配置他們的庫地址洪己。需要在這里配置妥凳,才能將第三方庫拉下來。

apply from: "config.gradle"
buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
        maven {
            url 'https://jitpack.io'
        }
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:1.0.2'
        classpath "io.realm:realm-gradle-plugin:4.1.1"
    }
}
allprojects {
    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
        maven {
            url 'https://jitpack.io'
        }
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
    }
}

apply from: "config.gradle" :外部配置文件答捕,下面會講到
buildscript和allprojects中都包含有repositories逝钥,是因?yàn)樗麄兊淖饔糜虿煌琤uildscript中的倉庫是gradle腳本自身需要的資源拱镐,而allprojects下的倉庫是項(xiàng)目所有模塊需要的資源艘款。

config.gradle

ext {

    android = [
            //編譯SDK的版本
            compileSdkVersion: 26,
            //buildtool 的版本
            buildToolsVersion: "26.0.2",
            //支持最小android sdk 版本
            minSdkVersion    : 17,
            // 目標(biāo)版本
            targetSdkVersion : 26
            //應(yīng)用版本號
            versionCode = 1
            //應(yīng)用版本名稱
            versionName = "v1.0.0"
    ]

    dependVersion = [
            support: "26.0.2"
    ]
    //服務(wù)器一 路由地址
    serverOneAPIUrl = [
            api_url_debug  : "\"https://devone.gradle.cn/\"",//開發(fā)
            api_url_test   : "\"https://testone.gradle.cn/\"",//內(nèi)測 
            api_url_preview: "\"https://preone.gradle.cn/\"",//預(yù)覽
            api_url_release: "\"https://one.gradle.cn/\""http://正式
    ]
   //服務(wù)器二 路由地址
   serverTwoAPIUrl = [
            api_chat_url_debug  : "\"https://devtwo.gradle.cn/\"",//開發(fā)
            api_chat_url_test   : "\"https://testtwo.gradle.cn/\"",//內(nèi)測
            api_chat_url_preview: "\"https://pretwo.gradle.cn/\"",//預(yù)覽
            api_chat_url_release: "\"https://two.gradle.cn/\""http://正式
    ]
    //服務(wù)器三 路由地址
    serverThreeUrl = [
            api_url_debug  : "\"https://devthree.gradle.cn/\"",//開發(fā)
            api_url_test   : "\"https://testthree.gradle.cn/\"",//內(nèi)測
            api_url_preview: "\"https://prethree.gradle.cn/\"",//預(yù)覽
            api_url_release: "\"https://three.gradle.cn/\""http://正式
    ]

    dependencies = [
            //------------- 分包  ------------
            multidex                  : "com.android.support:multidex:1.0.1",

            // ------------- Android -------------
            supportV4                 : "com.android.support:support-v4:${dependVersion.support}",
            appcompatV7               : "com.android.support:appcompat-v7:${dependVersion.support}",
            design                    : "com.android.support:design:${dependVersion.support}",
            cardview                  : "com.android.support:cardview-v7:${dependVersion.support}",
            junit                     : "junit:junit:4.12",

            // ------------- reyclerview ------------
            recyclerview              : "com.android.support:recyclerview-v7:${dependVersion.support}",

            // ------------- 網(wǎng)絡(luò)請求 -------------
            retrofit                  : 'com.squareup.retrofit2:retrofit:2.3.0',
            retrofit_rxjava           : 'com.squareup.retrofit2:adapter-rxjava2:2.3.0',
            retrofit_converter_gson   : 'com.squareup.retrofit2:converter-gson:2.3.0',
            okhttp_logging_interceptor: 'com.squareup.okhttp3:logging-interceptor:3.8.0',

            // ------------- 圖片加載 -------------
            glide                     : 'com.github.bumptech.glide:glide:4.3.1',
            glideAp                     : 'com.github.bumptech.glide:compiler:4.3.1',

            // ------------- 通信 -------------
            eventbus                  : 'org.greenrobot:eventbus:3.0.0',

            // ------------- RxAndroid -------------
            rxAndroid                 : 'io.reactivex.rxjava2:rxandroid:2.0.1',
            rxJava                    : 'io.reactivex.rxjava2:rxjava:2.0.1',

            // ------------- json解析 -------------
            gson                      : 'com.google.code.gson:gson:2.8.1',
    ]
}

項(xiàng)目配置文件持际,ext全局變量,在每個module的build.gradle文件中都可以隨時引用

module->build.gradle

apply plugin: 'com.android.application'
android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion

    //加載本地配置文件local.properties
    Properties properties = new Properties()
    InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream();
    properties.load(inputStream)

    //安卓構(gòu)建過程需要配置的參數(shù)
    defaultConfig {
        applicationId "com.demo.gradle"
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        multiDexEnabled true
        versionCode rootProject.ext.android.versionCode
        versionName rootProject.ext.android.versionName
    }
    //ndk配置參數(shù)
    ndk {
        abiFilters "armeabi-v7a", "arm64-v8a", "x86"
    }
    //java版本號
    compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
    }
    //渠道Flavors_打包
    productFlavors {
        //可以設(shè)置不同渠道渠道號哗咆,應(yīng)用名稱
        dev { // 開發(fā)
            buildConfigField "String", "CHANNEL_NUMBER", '"11111"'
        }
        '360' {
            buildConfigField "String", "CHANNEL_NUMBER", '"11112"'
        }
        GooglePlay {
            buildConfigField "String", "CHANNEL_NUMBER", "11113"'
    }

    //定義apk文件名稱格式
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}_${releaseFormatTime()}.apk")
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }

    //簽名
    signingConfigs {
        release {
            keyAlias properties.getProperty('keyAlias')
            keyPassword properties.getProperty('keyPassword')
            storeFile file(properties.getProperty('storeFile'))
            storePassword properties.getProperty('storePassword')
        }
    }

    buildTypes {
        debug {
            minifyEnabled false
            zipAlignEnabled false
            shrinkResources false
            (..各個服務(wù)器的dubug路由地址..)
        }

         preview {
            debuggable false // 是否保留調(diào)試信息
            minifyEnabled true  //是否混淆
            zipAlignEnabled true // 包優(yōu)化
            shrinkResources true // 移除不必要的資源
            // 簽名
            signingConfig signingConfigs.release
            // 代碼混淆規(guī)則文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            (..各個服務(wù)器的preview路由地址..)
        }

        release {
            //加上后綴
            applicationIdSuffix ".release"
            minifyEnabled true //是否混淆
            zipAlignEnabled true // zip對齊優(yōu)化
            shrinkResources true // 移除不必要的資源

            // 不顯示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"

            // 簽名
            signingConfig signingConfigs.release
            //混淆文件的位置
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            (..各個服務(wù)器的release路由地址..)
        }
    }

    // 為了解決部分第三方庫重復(fù)打包了META-INF的問題
    packagingOptions {
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/MANIFEST.MF'
        exclude 'sign.properties'
        exclude 'keystore.jks'
    }

    //執(zhí)行l(wèi)int檢查蜘欲,有任何的錯誤或者警告提示,都會終止構(gòu)建晌柬,我們可以將其關(guān)掉芒填。
    lintOptions {
        abortOnError false
    }
   
    dataBinding {
        enabled = true
    }

    dexOptions {
        //支持最大工程模式
        jumboMode = true 
        javaMaxHeapSize "10g"
        //使用增量模式
        //incremental false

        preDexLibraries = false //預(yù)編譯
        threadCount = "8" //線程數(shù)目
    }

}
//定義打包時間格式化
def releaseFormatTime() {
    return new Date().format("yyyy-MM-dd HH:mm", TimeZone.getDefault())
}

// 發(fā)布的日更新包時間尾巴
def releaseFormatDayTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getDefault())
}
// 定義打包時間戳
def releaseTime() {
    return new Date().getTime();
}

repositories {
    flatDir {
        dirs 'aars'
    }
    maven {
        url 'https://maven.google.com/'
        name 'Google'
    }
}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile rootProject.ext.dependencies.multidex
    compile rootProject.ext.dependencies.bugtags
    //------------  Android support  -----------
    //compile rootProject.ext.dependencies.supportV4
    compile rootProject.ext.dependencies.design
    compile rootProject.ext.dependencies.appcompatV7
    compile rootProject.ext.dependencies.cardview
    //------------  recyclerview  -------------
    compile rootProject.ext.dependencies.recyclerview
    compile rootProject.ext.dependencies.recyclerview_divider
    //------------  通信  --------------
    compile rootProject.ext.dependencies.eventbus
    //------------  網(wǎng)絡(luò)  ----------
    compile project(':api')
    //------------  rxAndroid-----------
    compile rootProject.ext.dependencies.rxAndroid
    compile rootProject.ext.dependencies.topsnackbar
    compile rootProject.ext.dependencies.glide
    annotationProcessor rootProject.ext.dependencies.glideAp
}

1.buildTypes是指建構(gòu)的類型,一般只用兩種默認(rèn)類型 debug 和 release空繁,顧名思義 debug 用來配置開發(fā)過程中的一些內(nèi)容殿衰;release 用來配置正式發(fā)布版本的內(nèi)容。有時我們需要發(fā)布介于debug與release之間的preview 版本盛泡。
2.簽名信息闷祥,可以直接將信息寫到gradle.properties或者,然后在然后在build.gradle中引用即可傲诵。
3.多渠道的關(guān)鍵在于定義不同的product flavor凯砍。這里的flavor名如果是數(shù)字開頭,必須用引號引起來拴竹。

BuildConfig

在build.gradle中配置buildConfigField參數(shù)悟衩,編譯后會在..\app\build\generated\source\buildConfig文件夾下會自動生成對應(yīng)版本對應(yīng)module的BuildConfig.java。BuildConfig就會包含對應(yīng)版本的配置信息栓拜。程序中可以直接引用這些數(shù)據(jù)畔派。例如BuildConfig.DEBUG。

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.demo.gradle";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "wandoujia";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "v1.0.0_debug";
  public static final int BUILD_TYPE_INT = 0;
  public static final boolean IS_DEBUG = true;
  (..各個服務(wù)器路由地址..)
}

module 調(diào)整目錄結(jié)構(gòu)sourceSets

默認(rèn)情況下赁温,java文件和resource文件分別在src/main/java和src/main/res目錄下价淌,在build.gradle文件,andorid{}里面添加下面的代碼啦鸣,便可以將java文件和resource文件放到src/java和src/resources目錄下潮饱。

sourceSets {
   min.java.srcDirs = ['src/java']
   min.resources.srcDirs = ['src/resources']
}

Gradle常用命令

./gradlew, ./代表當(dāng)前目錄,gradlew代表 gradle wrapper诫给,意思是gradle的一層包裝香拉,大家可以理解為在這個項(xiàng)目本地就封裝了gradle,即gradle wrapper中狂, myAPP/gradle/wrapper/gralde-wrapper.properties**文件中聲明了它指向的目錄和版本凫碌。只要下載成功即可用grdlew wrapper的命令代替全局的gradle命令。

理解了gradle wrapper的概念吃型,下面一些常用命令也就容易理解了证鸥。

./gradlew 下載更新gradle
./gradlew -v 版本號
./gradlew assemble 構(gòu)建項(xiàng)目輸出
./gradlew check 運(yùn)行檢測和測試任務(wù)
./gradlew clean 清除9GAG/app目錄下的build文件夾
./gradlew build 運(yùn)行check和assemble,檢查依賴并編譯打包
這里注意的是 ./gradlew build 命令把debug、release環(huán)境的包都打出來,如果正式發(fā)布只需要打Release的包枉层,該怎么辦呢泉褐,下面介紹一個很有用的命令 assemble<build type="" name="">, 如</build>
./gradlew assembleDebug 編譯并打Debug包
./gradlew assembleRelease 編譯并打Release的包所有渠道的
./gradlew assembleWandoujiaRelease 編譯并打包豌豆莢的Release版本
./gradlew assembleWandoujia 編譯并打包豌豆莢的所有版本
./gradlew installRelease Release模式打包并安裝
./gradlew uninstallRelease 卸載Release模式包

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鸟蜡,隨后出現(xiàn)的幾起案子膜赃,更是在濱河造成了極大的恐慌,老刑警劉巖揉忘,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跳座,死亡現(xiàn)場離奇詭異,居然都是意外死亡泣矛,警方通過查閱死者的電腦和手機(jī)疲眷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來您朽,“玉大人狂丝,你說我怎么就攤上這事』┳埽” “怎么了几颜?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長讯屈。 經(jīng)常有香客問我蛋哭,道長,這世上最難降的妖魔是什么涮母? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任谆趾,我火速辦了婚禮,結(jié)果婚禮上哈蝇,老公的妹妹穿的比我還像新娘棺妓。我一直安慰自己,他們只是感情好炮赦,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著样勃,像睡著了一般吠勘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上峡眶,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天剧防,我揣著相機(jī)與錄音,去河邊找鬼辫樱。 笑死峭拘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸡挠,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼辉饱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拣展?” 一聲冷哼從身側(cè)響起彭沼,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎备埃,沒想到半個月后姓惑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡按脚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年于毙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辅搬。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡唯沮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出伞辛,到底是詐尸還是另有隱情烂翰,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布蚤氏,位于F島的核電站甘耿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏竿滨。R本人自食惡果不足惜佳恬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望于游。 院中可真熱鬧毁葱,春花似錦、人聲如沸贰剥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚌成。三九已至前痘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間担忧,已是汗流浹背芹缔。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓶盛,地道東北人最欠。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓示罗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親芝硬。 傳聞我的和親對象是個殘疾皇子蚜点,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

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