Gradle

一拇舀、多工程配置

Gradle工程可以通過多工程配置來依賴其他的Gradle工程。
多工程配置通常把所有的工程作為"根目錄的子文件夾"蜻底;
比如下面的工程:

MyProject/
  app/
  libraries/
     lib1/
     lib2/

我們可以識別這三個工程骄崩。Gradle會通過如下名字引用它們:

:app
:libraries:lib1
:libraries:lib2

每個工程都有自己的build.gradle文件來定義如何構(gòu)建自己。
此外薄辅,工程的根目錄中有個settings.gradle的文件要拂,會定義所有的工程;
文件目錄結(jié)構(gòu)如下:

MyProject/
 settings.gradle
 app/
    build.gradle
 libraries/
    lib1/
       build.gradle
    lib2/
       build.gradle

settings.gradle文件中的配置如下:

include ':app',':libraries:lib1',':libraries:lib2'

這里定義了哪些文件是一個Gradle工程站楚;
:app工程也可能會依賴一些庫工程脱惰,可以通過如下腳本聲明依賴:

dependencies { compile projects(':libraries:lib1') }

二、庫工程
  • 普通工程和庫工程的不同:
    庫工程的main輸出的是一個.aar包窿春,它由編譯后的代碼(比如jar文件或者.so文件)以及資源文件(manifest拉一,res,assets)組成旧乞。 庫工程也可以生成一個測試apk蔚润,可以獨立于應(yīng)用進(jìn)行測試。
    它有相同的引導(dǎo)任務(wù)( assembleDebug , assembleRelease )尺栖,所以他和一般的工程沒有什么不同嫡纠。
    其余的,基本上都和應(yīng)用一樣了。他們都有build types和product flavors除盏,可以生成多個版本的aar叉橱。 注意 Build Type 大部分配置并不適用于庫工程。不過你可以依據(jù)庫工程是被其他工程依賴還是測試痴颊,然后通過自定義庫工程 sourceSet 改變它的內(nèi)容赏迟。
  • 庫工程的發(fā)布

默認(rèn)情況下庫工程只能發(fā)布release版本。這個版本用于所有工程的引用蠢棱,和工程要構(gòu)建什么樣的版本無關(guān)--這是屬于Gradle的限制锌杀;

三、根目錄的build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
//buildscripe{...}這部分用來配置驅(qū)動構(gòu)建的代碼
//這部分配置只會影響構(gòu)建過程泻仙,和工程沒有關(guān)系糕再;工程會定義它自己的倉庫和相關(guān)依賴
buildscript {
    //配置使用什么倉庫
    repositories {
        //指定倉庫URL快捷方式
        jcenter()
    }
    //配置 依賴什么插件
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'

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

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

/**
 * 設(shè)置全局參數(shù)
 * 可以在app/build.gradle中使用:
 * compileSdkVersion rootProject.ext.compileSdkVersion
 * buildToolsVersion rootProject.ext.buildToolsVersion
 */
ext {
    compileSdkVersion = 26
    buildToolsVersion = "26.0.2"
}
五、app下面的build.gradle
//配置應(yīng)用android插件玉转;
//備注:只應(yīng)用android插件就好了突想,不要同時應(yīng)用java插件,因為這會導(dǎo)致構(gòu)建錯誤
apply plugin: 'com.android.application'

import com.android.build.OutputFile

//可以從文件中讀取版本名字或者使用一些其他的自定義邏輯
def computeVersionName(){

    "1.0.2"http://不用寫return  默認(rèn)最后一行就是返回值
}

//配置了android構(gòu)建需要的所有參數(shù)究抓,默認(rèn)情況下只有編譯sdk的版本(compileSDKVersion)猾担、構(gòu)建工具版本(buildToolsVersion)是必須的;
//android 元素里的 defaultConfig 負(fù)責(zé)定義所有的配置刺下。
android {
    //使用全局配置--配置見project/build.gradle
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
    defaultConfig {
        applicationId "com.zcbl.client.zcblsdk"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 1
        versionName computeVersionName()
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk{
            //生成.so的名字
            moduleName "hello"

        }

//        multiDexEnabled true
    }

    /**
     * 這前用上面multiDexEnabled true時绑嘹,
     * 突然在5.0以下的手機上跑不起來,
     * 改成下面這種寫法就可以了橘茉。
     */
    dexOptions {
        jumboMode true
    }

    buildTypes {
        release {
            minifyEnabled false
            //有兩個默認(rèn)的規(guī)則文件
            //1.proguard-android.txt
            //2.proguard-android-optimize.txt
            //它們都位于SDK中工腋,使用getDefaultProguardFile()方法可以返回文件的全路徑。二者除了是否開啟優(yōu)化之外畅卓,其他功能全相同擅腰;
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // 構(gòu)建類型是否應(yīng)該生成可調(diào)試的apk
//            debuggable true
        }

        debug {
            //配置了默認(rèn)debug的構(gòu)建類型:設(shè)置包名以.debug為后綴,這樣和release的包名不一致了翁潘,就能在同一個設(shè)備上\
            //                        同時安裝debug和release兩個版本的APK
            applicationIdSuffix ".debug"
            //構(gòu)建類型是否配置為使用可調(diào)試的本機代碼生成APK
//            jniDebuggable true
            //注意:使用此配置趁冈,需要注釋點res/strings/中的app_name ,用來動態(tài)配置不同app的名字
//            resValue('string','app_name','測試版')

        }

        //創(chuàng)建一個buildTypes很簡單拜马,只需要在buildTypes容器中添加一個元素箱歧,然后調(diào)用initWith()或者使用一個閉包配置它;
        //initWith所傳的參數(shù)是為了配置作為哪個(release或者debug)的副本一膨,也就說打出來的包用什么證書簽名;
        //如果不傳參數(shù)洒沦,將會打出一個沒有被簽名的apk文件
        jnidebug.initWith(buildTypes.debug)

        jnidebug {
            applicationIdSuffix ".jnidebug"
//            packageNameSuffix ".jnidebug"http://decorated
            jniDebuggable true
            versionNameSuffix ".debug"
//            signingConfig
//            proguardFile
//            proguardFiles
//            minifyEnabled
//            zipAlignEnabled
//            debuggable
//            jniDebuggable
//            renderscriptDebuggable
//            renderscriptOptimLevel
//            manifestPlaceholders = [PGY_PGYER_APPID:"********"]
//            buildConfigField('String','API_URL','\"http://www.baidu.com\"')
        }

    }



    //通常情況下豹绪,Build Type 配置會覆蓋其他配置,比如,Build Type 的 packageNameSuffix 會追加到 Product Flavor 的 packageName 之后瞒津。

    //也有一些情況是在 Build Type 和 Product Flavor 中都可以設(shè)置蝉衣,在這種情況下,視情況而定巷蚪。

    //比如病毡, signingConfig 就是這么一個屬性。 通過設(shè)置 android.buildTypes.release.signingConfig 屁柏,可以為所
    // 有的release包共享相同的SigningConfig啦膜,也可以單獨通過設(shè)置android.productFlavors.*.signingConfig為每
    // 一個release包指定他們自己的 SigningConfig 。



    /**
     * //指定兩個維度:是否付費和發(fā)布的平臺
     * flavorDimensions中定義的Dimensions排序很重要:這個排序決定了哪一個flavor中設(shè)置的屬性覆蓋哪一個淌喻,因為一個flavor中的
     *                  值(設(shè)置的屬性)會被替換定義在底優(yōu)先級的flavor中的值(屬性)僧家;比如下面"發(fā)布平臺(store)"中設(shè)置的versionName會
     *                  覆蓋"是否付費(price)"中設(shè)置的versionName,也就是打出的包的versionName對應(yīng)為:google,amazon,baidu;
     *                  但高優(yōu)先級的會覆蓋低優(yōu)先級的資源--也就是res目錄下的資源文件會遵循優(yōu)先級覆蓋的原則裸删;
     */
    flavorDimensions "price","store"

    //android.productFlavors.*是ProductFlavor類型的八拱,和android.defaultConfig對象具有相同的類型,這就意味著他們有相同的屬性涯塔;
    //defalutConfig為所有的flavor提供了基本的配置肌稻,每一個falvor也都可以重新設(shè)置覆蓋這些默認(rèn)值;

    productFlavors{
        //favours的名字不能和Build Types 名字或者androidTest SourceSet沖突
        //每一個favours都可以通過一個閉包單獨設(shè)置
        google{
            versionName 'google'
            dimension "store"
        }
        amazon{
            versionName 'amazon'
            dimension "store"
//            manifestPlaceholders = [PGY_PGYER_APPID:"********"]
            buildConfigField 'String','API_URL','\"API_URL_FLAVOR2\"'
            buildConfigField("boolean","LOG_DEBUG","false")
        }
        baidu{
            versionName 'baidu'
            dimension 'store'
        }
        free{
            versionName 'free'
            dimension 'price'
        }
        paid{
            versionName 'paid'
            dimension 'price'
        }

//        //下面的只有沒有設(shè)置flavorDimensions時才能編譯通過
//        tx{
//            versionName 'tx'
//        }
    }


    sourceSets {
//        main {
//            //修改項目目錄:使用場景-->就是eclipse項目轉(zhuǎn)Android studio項目匕荸,需要重新配置項目結(jié)構(gòu)
//            //要替換默認(rèn)的源文件夾的話爹谭,可以給 srcDirs 指定一個路徑數(shù)組
//            manifest.srcFile 'AndroidManifest.xml'
//            java.srcDirs = ['src']
//            resources.srcDirs = ['src']
//            aidl.srcDirs = ['src']
//            renderscript.srcDirs = ['src']
//            res.srcDirs = ['res']
//            assets.srcDirs = ['assets']
//        }
    //不同產(chǎn)品不同的文件
//        falvor1 {
//            java.srcDirs = ['src/product/java']
//        }
//        falvor2 {
//            java.srcDirs = ['src/temp/java']
//        }
    }
//    //注意:srcDir 會添加指定的文件夾到現(xiàn)有的源文件夾列表中(Gradle文檔沒有提到這個,但是的確是這樣的)

//當(dāng)默認(rèn)的工程結(jié)構(gòu)不適用的時候每聪,你可能需要配置它旦棉。根據(jù)Gradle文檔說明,可以通過如下方式重新配置Java工程的 sourceSets:
//    sourceSets {
//        main {
//            java {
//                srcDir 'src/java' // 指定源碼目錄
//            }
//            resources {
//                srcDir 'src/resources'//資源目錄
//            }
//            assets {
//                srcDir 'src/assets'
//            }
//        }
//    }

    /**
     * 主要用來配置打包時药薯,來從哪里打包資源或者代碼
     * 說白了 就是告訴編譯器你從哪個文件下找出代碼绑洛,打包進(jìn)apk文件里
     */
//    sourceSets {
//        main() {
//            jniLibs.srcDirs = ['src/main/libs']
//            jni.srcDirs = []
//        }
//    }

    /**
     * 一般應(yīng)該盡可能的建立一個單一的apk,這個apk可以支持所有的目標(biāo)設(shè)備童本,但是這會導(dǎo)致一個apk包體積非常大真屯;因為這個apk
     * 支持所有"屏幕密度"或"應(yīng)用二進(jìn)制接口"(ABI).
     * 減少apk體積的一種方法,就是創(chuàng)建支持特定屏幕密度或者abi的apk穷娱。
     *
     * Gradle可以使用splits來進(jìn)行apk拆分:
     * 需要在splits{}中添加density{}或者abi{}閉包函數(shù)绑蔫;
     * 參數(shù)說明:
     * enable:如果為true,Gradle會根據(jù)定義的屏幕密度或者abi來生成指定屏幕密度或者abi的apk包泵额;默認(rèn)為false配深;
     * exclude:用來排除應(yīng)用不需要支持的屏幕密度或者abi,支持的類型一般用逗號分隔嫁盲;
     * include:與exclude對應(yīng)篓叶,只能與reset()結(jié)合使用才能指定支持的屏幕密度或者abi;支持的類型一般用逗號分隔;
     * reset():清除默認(rèn)支持的屏幕密度或abi缸托。注意:這個方法僅當(dāng)與include元素組合使用時才能添加指定的屏幕密度或者abi左敌;
     * 比如設(shè)置支持密度為ldpi和xxhdpi的設(shè)置如下:
     * splits{
     *     //density提供所需的屏幕密度和兼容的屏幕尺寸的列表
     *     density{
     *         reset()
     *         include "ldpi","xxhdpi"
     *     }
     * }
     *
     * compatibleScreens:指定兼容的屏幕尺寸,指定多個尺寸使用逗號分隔俐镐;這將在每個拆分的apk的manifest中注入匹配的<compatible-screens>節(jié)點矫限;
     * 這個可選設(shè)置提供了在同一個build.gradle中管理屏幕密度和屏幕大小的方法;但是使用<compatible-screens>將限制應(yīng)用程序使用的設(shè)配類型佩抹;
     * universalApk:這個是abi獨有的一個配置叼风;如果為true,Gradle將會生成包含所有abi的通用abi以及拆分的apk匹摇,通用apk中包含所有的abi代碼和資源咬扇;
     *              默認(rèn)值為false.
     *              密度APK分裂總是生成一個通用的APK,包含所有屏幕密度的代碼和資源廊勃。
     */
//    splits{
//
////        density{
////            enable true
////            exclude "ldpi","xxhdpi","xxxhdpi"
////            compatibleScreens 'small','normal','large','xlarge'
////        }
//
//        abi{
//            enable true
//            reset()
//            include 'x86','armeabi-v7a'
//            universalApk true
//        }
//    }

    // map for the version code
//    project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]
//
//    // applicationVariants are e.g. debug, release
//    applicationVariants.all { variant ->
//        variant.outputs.each { output ->
//            // For each separate APK per architecture, set a unique version code as described here:
//            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
////            def versionCodes = ["armeabi-v7a": 1, "x86": 2]
//
//            def abi = output.getFilter(OutputFile.ABI)
//            if (abi != null) {  // null for the universal-debug, universal-release variants
//                output.versionCodeOverride = project.ext.versionCodes.get(abi) * 100 + defaultConfig.versionCode
//            }
//        }
//    }

}

/**
 * 為了打包出不同versionCode值的配置
 * 下面的意思:將打出的x86的apk包的versionCode修改為301懈贺,將打出的armeabi-v7a的apk包的versionCode修改為:101
 * 同android節(jié)點下的配置效果一樣
 */
project.ext.versionCodes = ['armeabi-v7a':1, mips:2, x86:3]
android.applicationVariants.all { variant ->
    // assign different version code for each output
    variant.outputs.each { output ->
        def abi = output.getFilter(OutputFile.ABI)
        if (null != abi) {
            output.versionCodeOverride = project.ext.versionCodes.get(abi) * 100 + android.defaultConfig.versionCode
        }

    }
}



//注:dependencies DSL元素是標(biāo)準(zhǔn)Gradle API的一部分,并不屬于android的元素
dependencies {
    //compile 配置用來編譯main application坡垫,它里面的一切都會被添加到編譯的classpath中梭灿,并且也會被打包到最終的apk中
    //compile : main application
    //androidTestCompile: test application
    //debugCompile: debug Build Type
    //releaseCompile: release Build Type
    //因為要構(gòu)建生成一個APK,必然會有相關(guān)聯(lián)的Build Type,APK默認(rèn)配置兩個(或者更多)編譯配置:compile和<buildtpe>Compile.
    //創(chuàng)建一個新的Build Type 的時候會自動創(chuàng)建一個基于它名字的編譯配置;
    //當(dāng)一個debug版本需要一個自定義庫(比如報告崩潰)冰悠,但是release版本不需要或者需要一個不同版本的庫的時候堡妒,會顯得非常有用;
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
    //配置依賴一個外部庫jar包溉卓,可以在compile配置里添加一個依賴
//    compile files('libs/foo.jar')
    debugCompile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
    //引用一個根目錄下的庫工程方式如下:
//    compile project(':libraries:lib1')

    //設(shè)置不同的產(chǎn)品引入不同的包
//    falvor1Compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
}

////生成arr
//repositories {
//    flatDir {
//        dirs 'aars'
//    }
//}
////使用aar
//dependencies {
//    compile(name:'libraryname', ext:'aar')
//}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末皮迟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子桑寨,更是在濱河造成了極大的恐慌伏尼,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尉尾,死亡現(xiàn)場離奇詭異爆阶,居然都是意外死亡,警方通過查閱死者的電腦和手機沙咏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門辨图,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肢藐,你說我怎么就攤上這事故河。” “怎么了吆豹?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵忧勿,是天一觀的道長杉女。 經(jīng)常有香客問我,道長鸳吸,這世上最難降的妖魔是什么斤寂? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任狞玛,我火速辦了婚禮识补,結(jié)果婚禮上痘儡,老公的妹妹穿的比我還像新娘缕题。我一直安慰自己廓块,他們只是感情好秋度,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布瓶盛。 她就那樣靜靜地躺著都伪,像睡著了一般呕乎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上陨晶,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天猬仁,我揣著相機與錄音,去河邊找鬼先誉。 笑死湿刽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的褐耳。 我是一名探鬼主播诈闺,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼铃芦!你這毒婦竟也來了雅镊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤刃滓,失蹤者是張志新(化名)和其女友劉穎仁烹,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體注盈,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡晃危,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了老客。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片僚饭。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖胧砰,靈堂內(nèi)的尸體忽然破棺而出鳍鸵,到底是詐尸還是另有隱情,我是刑警寧澤尉间,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布偿乖,位于F島的核電站击罪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏贪薪。R本人自食惡果不足惜媳禁,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望画切。 院中可真熱鬧竣稽,春花似錦、人聲如沸霍弹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽典格。三九已至岛宦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耍缴,已是汗流浹背砾肺。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留私恬,地道東北人债沮。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像本鸣,于是被迫代替她去往敵國和親疫衩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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

  • 結(jié)束了詞匯的部分荣德,今天開始就進(jìn)入了拼寫闷煤,作者提到了一些方法如眼部訓(xùn)練、聯(lián)想記憶等方法通過訓(xùn)練你的大腦來消除拼寫錯誤...
    泥巴叔叔閱讀 221評論 0 1
  • 夜 吟 文|又人 這天涮瞻,總是夜起幽涼鲤拿,這夜,總是勾起悲愴署咽。 無月之夜近顷,與老莊騎車行于街道,...
    又人同學(xué)閱讀 561評論 0 3
  • 創(chuàng)造1 就我的本心來講宁否,我想送人肯定是買當(dāng)?shù)氐暮弥仙R亲约撼裕瑢W(xué)長的月餅口感和質(zhì)量確實不錯的慕匠。但是這東西自己吃饱须,也...
    我和榕樹閱讀 242評論 0 0
  • 荷花拍的多了,再次面對台谊,便失去拍攝的興趣蓉媳。既然了然無趣譬挚,索性換個主題。又是蓮花綻開的時節(jié)酪呻,和麻豆約定了時間賞荷拍花...
    芥空閱讀 210評論 2 2
  • 初遇時是在草長鶯飛的春天号杠,殊不知蚪腋,那意外的一眼,陌生的悸動姨蟋,從此便持續(xù)了幾年。 楔子 坊間傳言立帖,在驪山深處有...
    遠(yuǎn)鎮(zhèn)閱讀 1,551評論 8 31