Gradle

一、多工程配置

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

MyProject/
  app/
  libraries/
     lib1/
     lib2/

我們可以識(shí)別這三個(gè)工程。Gradle會(huì)通過如下名字引用它們:

:app
:libraries:lib1
:libraries:lib2

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

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

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

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

這里定義了哪些文件是一個(gè)Gradle工程;
:app工程也可能會(huì)依賴一些庫工程,可以通過如下腳本聲明依賴:

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

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

默認(rèn)情況下庫工程只能發(fā)布release版本。這個(gè)版本用于所有工程的引用,和工程要構(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ū)動(dòng)構(gòu)建的代碼
//這部分配置只會(huì)影響構(gòu)建過程,和工程沒有關(guān)系;工程會(huì)定義它自己的倉庫和相關(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插件就好了,不要同時(shí)應(yīng)用java插件,因?yàn)檫@會(huì)導(dǎo)致構(gòu)建錯(cuò)誤
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時(shí),
     * 突然在5.0以下的手機(jī)上跑不起來,
     * 改成下面這種寫法就可以了。
     */
    dexOptions {
        jumboMode true
    }

    buildTypes {
        release {
            minifyEnabled false
            //有兩個(gè)默認(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的包名不一致了,就能在同一個(gè)設(shè)備上\
            //                        同時(shí)安裝debug和release兩個(gè)版本的APK
            applicationIdSuffix ".debug"
            //構(gòu)建類型是否配置為使用可調(diào)試的本機(jī)代碼生成APK
//            jniDebuggable true
            //注意:使用此配置,需要注釋點(diǎn)res/strings/中的app_name ,用來動(dòng)態(tài)配置不同app的名字
//            resValue('string','app_name','測試版')

        }

        //創(chuàng)建一個(gè)buildTypes很簡單,只需要在buildTypes容器中添加一個(gè)元素,然后調(diào)用initWith()或者使用一個(gè)閉包配置它;
        //initWith所傳的參數(shù)是為了配置作為哪個(gè)(release或者debug)的副本,也就說打出來的包用什么證書簽名;
        //如果不傳參數(shù),將會(huì)打出一個(gè)沒有被簽名的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 配置會(huì)覆蓋其他配置,比如,Build Type 的 packageNameSuffix 會(huì)追加到 Product Flavor 的 packageName 之后。

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

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



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

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

    productFlavors{
        //favours的名字不能和Build Types 名字或者androidTest SourceSet沖突
        //每一個(gè)favours都可以通過一個(gè)閉包單獨(dú)設(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時(shí)才能編譯通過
//        tx{
//            versionName 'tx'
//        }
    }


    sourceSets {
//        main {
//            //修改項(xiàng)目目錄:使用場景-->就是eclipse項(xiàng)目轉(zhuǎn)Android studio項(xiàng)目,需要重新配置項(xiàng)目結(jié)構(gòu)
//            //要替換默認(rèn)的源文件夾的話,可以給 srcDirs 指定一個(gè)路徑數(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 會(huì)添加指定的文件夾到現(xiàn)有的源文件夾列表中(Gradle文檔沒有提到這個(gè),但是的確是這樣的)

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

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

    /**
     * 一般應(yīng)該盡可能的建立一個(gè)單一的apk,這個(gè)apk可以支持所有的目標(biāo)設(shè)備,但是這會(huì)導(dǎo)致一個(gè)apk包體積非常大;因?yàn)檫@個(gè)apk
     * 支持所有"屏幕密度"或"應(yīng)用二進(jìn)制接口"(ABI).
     * 減少apk體積的一種方法,就是創(chuàng)建支持特定屏幕密度或者abi的apk。
     *
     * Gradle可以使用splits來進(jìn)行apk拆分:
     * 需要在splits{}中添加density{}或者abi{}閉包函數(shù);
     * 參數(shù)說明:
     * enable:如果為true,Gradle會(huì)根據(jù)定義的屏幕密度或者abi來生成指定屏幕密度或者abi的apk包;默認(rèn)為false;
     * exclude:用來排除應(yīng)用不需要支持的屏幕密度或者abi,支持的類型一般用逗號(hào)分隔;
     * include:與exclude對應(yīng),只能與reset()結(jié)合使用才能指定支持的屏幕密度或者abi;支持的類型一般用逗號(hào)分隔;
     * reset():清除默認(rèn)支持的屏幕密度或abi。注意:這個(gè)方法僅當(dāng)與include元素組合使用時(shí)才能添加指定的屏幕密度或者abi;
     * 比如設(shè)置支持密度為ldpi和xxhdpi的設(shè)置如下:
     * splits{
     *     //density提供所需的屏幕密度和兼容的屏幕尺寸的列表
     *     density{
     *         reset()
     *         include "ldpi","xxhdpi"
     *     }
     * }
     *
     * compatibleScreens:指定兼容的屏幕尺寸,指定多個(gè)尺寸使用逗號(hào)分隔;這將在每個(gè)拆分的apk的manifest中注入匹配的<compatible-screens>節(jié)點(diǎn);
     * 這個(gè)可選設(shè)置提供了在同一個(gè)build.gradle中管理屏幕密度和屏幕大小的方法;但是使用<compatible-screens>將限制應(yīng)用程序使用的設(shè)配類型;
     * universalApk:這個(gè)是abi獨(dú)有的一個(gè)配置;如果為true,Gradle將會(huì)生成包含所有abi的通用abi以及拆分的apk,通用apk中包含所有的abi代碼和資源;
     *              默認(rèn)值為false.
     *              密度APK分裂總是生成一個(gè)通用的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é)點(diǎn)下的配置效果一樣
 */
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,它里面的一切都會(huì)被添加到編譯的classpath中,并且也會(huì)被打包到最終的apk中
    //compile : main application
    //androidTestCompile: test application
    //debugCompile: debug Build Type
    //releaseCompile: release Build Type
    //因?yàn)橐獦?gòu)建生成一個(gè)APK,必然會(huì)有相關(guān)聯(lián)的Build Type,APK默認(rèn)配置兩個(gè)(或者更多)編譯配置:compile和<buildtpe>Compile.
    //創(chuàng)建一個(gè)新的Build Type 的時(shí)候會(huì)自動(dòng)創(chuàng)建一個(gè)基于它名字的編譯配置;
    //當(dāng)一個(gè)debug版本需要一個(gè)自定義庫(比如報(bào)告崩潰),但是release版本不需要或者需要一個(gè)不同版本的庫的時(shí)候,會(huì)顯得非常有用;
    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'
    //配置依賴一個(gè)外部庫jar包,可以在compile配置里添加一個(gè)依賴
//    compile files('libs/foo.jar')
    debugCompile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
    //引用一個(gè)根目錄下的庫工程方式如下:
//    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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 結(jié)束了詞匯的部分,今天開始就進(jìn)入了拼寫,作者提到了一些方法如眼部訓(xùn)練、聯(lián)想記憶等方法通過訓(xùn)練你的大腦來消除拼寫錯(cuò)誤...
    泥巴叔叔閱讀 300評論 0 1
  • 夜 吟 文|又人 這天,總是夜起幽涼,這夜,總是勾起悲愴。 無月之夜,與老莊騎車行于街道,...
    又人同學(xué)閱讀 655評論 0 3
  • 創(chuàng)造1 就我的本心來講,我想送人肯定是買當(dāng)?shù)氐暮谩R亲约撼?,學(xué)長的月餅口感和質(zhì)量確實(shí)不錯(cuò)的。但是這東西自己吃,也...
    我和榕樹閱讀 284評論 0 0
  • 荷花拍的多了,再次面對,便失去拍攝的興趣。既然了然無趣,索性換個(gè)主題。又是蓮花綻開的時(shí)節(jié),和麻豆約定了時(shí)間賞荷拍花...
    芥空閱讀 282評論 2 2
  • 初遇時(shí)是在草長鶯飛的春天,殊不知,那意外的一眼,陌生的悸動(dòng),從此便持續(xù)了幾年。 楔子 坊間傳言,在驪山深處有...
    遠(yuǎn)鎮(zhèn)閱讀 1,750評論 8 31

友情鏈接更多精彩內(nèi)容