gradle android基本配置詳解

二度看風景發表於2017-09-24
apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"

    defaultConfig {
        /**
         * 屬性的配置
         */
        applicationId "cct.cn.gradle.lsn13"
        applicationIdSuffix "" // applicationId的字尾  最後組成的是cct.cn.gradle.lsn13.suffix
        minSdkVersion 14
        targetSdkVersion 25
        versionCode  1
        versionName "1.0"
        versionNameSuffix ".12"  // versionName  最後組成的是1.0.12

        //manifest佔位符 給manifest傳遞變數
        manifestPlaceholders = [key:'xyz']

        //65535問題 0xffff是否開啟分包dex
        multiDexEnabled true
        //每一行表示要配置到主dex的一個類 com/a/c/c.class 配置分包規則
        multiDexKeepFile file('keep_in_main.txt')
        //-keep com.a.b.c.**{*;} proguard寫法的的分包規則
        multiDexKeepProguard

        //測試引擎
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        //配置ndk的一些規則
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }

            //配置Gradle 構建時需要的.so動態庫
            // Gradle會構建那些 ABI 配置,但是隻會將 defaultConfig.ndk {} 程式碼塊中指定的配置打包到 apk 中
            ndkBuild{
                abiFilters 'armeabi','armeabi-v7a'
            }
        }

        //指打包到apk裡面的.so包種類
        ndk{
            abiFilters 'armeabi','armeabi-v7a'
        }

        //支援svg
        vectorDrawables{
            //如果minsdk小於21 會在mdpi的目錄png圖片
            generatedDensities 'mdpi'
            //如果設定為true 引入svg相容包 不會再去管generatedDensities配置
            // 建議只選下面這個就好了 丟棄generatedDensities
            useSupportLibrary true
        }

        //能支援部分java8的特性 比如lambda
        jackOptions {
            enabled false
        }

        //可以配置Java的一些方法  比如apt註解處理器
        javaCompileOptions{

        }

        /**
         * 下面是方法使用
         */
        //配置在build/generated/source/buildConfig/ 下面有個BuildConfig檔案下的屬性
        buildConfigField('boolean','IS_RELEASE','false')

        //  res/value 設定一個值  之後就而已呼叫R.string.lin了
        //  生成的結果是<string name="lin" translatable="false">linyao</string>
        resValue('string','lin','linyao')
    }

    /**
     * 建立兩個維度 維度是配合 productFlavors一起使用的
     * 下面一個時產品維度  一個時動態庫維度
     */
    flavorDimensions('product','abi')

    /**
     * 建立產品風味 相當於整合了defaultConfig的屬性  這裡可以修改自己風味(變體)的屬性
     * 不同的維度的風味結合在一起 組成一個apk的配置資訊
     */
    productFlavors{
        free{
            dimension 'product'

            //這個屬性是覆蓋defaultConfig的
            manifestPlaceholders = [key: '66']

            //這個兩個是追加在defaultConfig的
            applicationIdSuffix ""
            versionNameSuffix ".16"
        }

        pro{
            dimension 'product'
            manifestPlaceholders = [key: 'product']
        }

        x86{
            dimension 'abi'
        }

        arm{
            dimension 'abi'
        }

    }

    /**
     *    過濾風味(變體) 下面例子過濾pro變體
     */
    variantFilter{
        variant ->
            variant.flavors.each{
                if(it.name.contains('pro')){
                    setIgnore(true)
                }
            }
    }

    /**
     * 配置簽名檔案 裡面可以配置多個簽名檔案
     */
    signingConfigs{
        mySign{
            //簽名檔案的路徑
            storeFile file('debug.keystore')
            //簽名檔案密碼
            storePassword 'android'
            //別名
            keyAlias 'androiddebygkey'
            //key的密碼
            keyPassword 'android'
        }
    }

    /**
     * 變體
     * buildTypes和defaultConfig繼承自同一個類 很多東西兩者都可以配置
     */
    buildTypes {
        release {
            //選擇配置的簽名檔案
//            signingConfig signingConfigs.mySign

            //proguard 優化是否開啟 true的時候會進行程式碼混淆 並優化程式碼 去掉多餘無用的類
            minifyEnabled true

            //將下面兩個混淆檔案都放在混淆檔案proguardFiles中
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            //優化壓縮資原始檔 和minifyEnabled配合使用 必須開啟混淆 這個可以減少apk的大小
            shrinkResources true
        }

        debug{
            /**
             * 屬性
             */
            //和defaultConfig中配置是一樣的  這個會累加到defaultConfig中配置的applicationId後面
            applicationIdSuffix ''

            //版本名字字尾,用法同上
            versionNameSuffix '.1'

            //生成的apk是否可以除錯 預設是true
            debuggable true

            //是否可以除錯NDK程式碼 使用lldb進行c和c++程式碼除錯
            jniDebuggable true

            //幫助國際化的東西 然而並沒有什麼用 會多幾個string的國際化的資料
            pseudoLocalesEnabled false

            //是否開啟渲染指令碼 就是一些c寫的渲染方法
            renderscriptDebuggable false

            //渲染指令碼等級 預設是5
            renderscriptOptimLevel 5

            //用jacoco 報告測試覆蓋率的 必須是機器測試不能是本地測試(要在test檔案加下 不能是androidTest資料夾)
            testCoverageEnabled false

            //優化 預設就是true app對齊
            zipAlignEnabled true

            /**
             * 方法
             */
            //配置在build/generated/source/buildConfig/ 下面有個BuildConfig檔案下的屬性
            buildConfigField('boolean','IS_RELEASE','false')
        }

        hello{
            //就是整合子debug 整合debug所有的配置
            initWith debug
        }
    }

    /**
     * 設定構建ndk的CMakeLists檔案
     */
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

    /**
     * 打包時候用的 Android資原始檔編譯工具
     */
    aaptOptions{
        //aapt執行時的額外引數 例如下面就是增加一條修改AndroidManifest包名的一條密令
        //還可以在引數後面加 '-S','src/main/res2','--auto-add-overlay'實現重疊包,這樣res 和res2裡面的資源會疊加
        //如果有重複的 以res為準
        additionalParameters '--rename-manifest-package',
                'cct.cn.gradle.lsn13','-S','src/main/res2','--auto-add-overlay'

        //對png進行優化檢查 預設true
        //比如把.jpg格式圖片改成.png字尾 那開啟這個檢查後編譯就會報錯 能夠把這個錯誤檢測出來
        cruncherEnabled true

        //對res目錄下的資原始檔進行排除 比如下面的寫法 就不會把res資料夾下面的所有.jpg格式的檔案打包到apk中
        //注意: 這個只排除res目錄下的檔案  不排除assets目錄下的
        ignoreAssets '*.jpg'

        //對資原始檔不進行壓縮 預設是對.png .jpg等檔案不壓縮 對.xml等檔案都進行壓縮
        //如果寫成空字串 '' 則對所有檔案都不壓縮
        //下面是表示對所有.bat檔案不進行壓縮
        //運用 aapt l -v app/build/outputs/apk/app-debug.apk 可以檢視這個apk的資原始檔的壓縮情況
        noCompress '.bat'

    }

    /**
    * 資源合併規則 下面是規則 前面的會覆蓋後面的
    * Variant(freeDebug變體檔案) > buildType(Debug) > flavor(hello) > (main >aapt -S) > dependencies
    * /
    /**
     * 資源整合
     */
    sourceSets{
        main{
            //這裡如果res和myres中有衝突資源會報錯  不像aapt裡面會議res優先
            res.srcDirs 'src/main/res','src/main/myres'

            //把lib裡面的資源整合到jniLibs裡 指定.so檔案目錄
            jniLibs.srcDirs = ['libs']

            //下面是所有可以指定的目錄 可以自己更改
            aidl.srcDirs 'src/main/aidl'
            assets.srcDirs 'src/main/assets'
            java.srcDirs 'src/main/java'
            jni.srcDirs 'src/main/jni'
            renderscript.srcDirs 'src/main/renderscript' // 渲染指令碼目錄
            resources.srcDirs 'src/main/resources'

            //這個是指定manifest檔案 不是指定目錄
            manifest.srcFile 'src/main/AndroidManifest.xml'

            //這個就是main 名字 跟release debug 一樣
            name

            //下面的不需要考慮
            compileConfigurationName //compile編譯+打包的依賴配置組的名字 這個不能改 也沒啥用
            packageConfigurationName //apk 打包
            providedConfigurationName // provided 編譯
        }

        //不僅僅可以指定main裡的目錄配置 還可以指定風味的配置(比如多渠道打包)
        //如果打的包是free風味包 那出來的apk會把free目錄裡的檔案疊加到main裡
        free{

        }
    }

    /**
     * adb命令的一些操作
     */
    adbOptions{
        //呼叫adb install命令時可以傳遞的引數
        //例如: 呼叫adb install -d 可以安裝低版本的apk  -r 替換已經存在的application
        installOptions '-d'

        //執行adb命令的時候設定的一個超時時間 單位毫秒
        timeOutInMs 1000
    }

    /**
     *  編譯的一些配置
     */
    compileOptions{
        //java原始檔的編碼格式 預設UTF-8
        encoding 'UTF-8'

        //java編譯是否使用gradle新的增量模式 (這個就不需要管它了)
        incremental true

        //java原始檔編譯的jdk版本 預設是1.6 也可以指定1.7
        //但是不能指定1.8 除非開啟了jackOptions  下面這個兩個屬性也沒什麼用 開啟了jack自然可以用1.8的特性了
        sourceCompatibility JavaVersion.VERSION_1_7
        //編譯出的class的版本
        targetCompatibility JavaVersion.VERSION_1_7
    }

    /**
     *  android提供的view和資料繫結的工具
     *  詳細用法見官網http://developer.android.com/:搜尋dataBinding
     */
    dataBinding {
        enabled true
    }

    /**
     * dx配置 打包時的分包工具
     */
    dexOptions{
        //指定附加的引數 像aaptOptions的additionalParameters  使用dx命令
        //和multiDexEnabled multiDexKeepFile配合使用 --main-dex-list命令會讀取multiDexKeepFile指定的keep檔案
        //--minimal-main-dex 表示設定主dex儘量最小 這樣就算方法數不到65535 也可以開啟分包
        //--set-max-idx-number 表示單個dex裡面的最多id數 這樣就會打出很多的dex包
        additionalParameters '--minimal-main-dex','--set-max-idx-number=10000'

        //執行dx時java虛擬機器需要的記憶體大小 如果報記憶體不夠錯誤  可以把下面的數字變大點
        javaMaxHeapSize '2048m'

        //開啟大模式 dex大 如果=true 編譯出的dex能夠儘量大 存放更多的類
        jumboMode true

        //在dex中是否保留Runtime註解 預設是true
        keepRuntimeAnnotatedClasses true

        //預設dex中的程式數  預設是4  也沒有必要修改
        maxProcessCount 4

        //預設的執行緒數
        threadCount 4

        //對library預編譯 提高編譯效率 但是會使clean的時候比較慢  預設開啟的
        preDexLibraries true
    }

    /**
     * lint工具配置 lint工具幫助發現並糾正程式碼結構質量 檢查未使用的資源
     */
    lintOptions{

        //預設true 表示當執行lint過程中發現錯誤 就停止構建
        abortOnError true
        //檢測出錯誤時 輸出絕對路徑
        absolutePaths true
        //指定檢測的id 設定這個屬性後  只檢測這一個id
//        check 'UnusedResources'
        //是否檢查所有警告
        checkAllWarnings false
        //在release的buildType下是否檢查fatal錯誤 如果有fatal錯誤 則會停止構建 預設true
        checkReleaseBuilds true
        //開啟某一個id的檢查
        enable 'UnusedResources'
        //關閉某一id的檢查
        disable 'UnusedResources'

        //html的輸出檔案 傳遞一個檔案
//        htmlOutput
        //執行檢查的報告 是否需要生成 htmlOutput報告 預設true
        htmlReport true

        //xml的輸出檔案 傳遞一個檔案
//        xmlOutput
        //執行檢查的報告 是否需要生成xml報告 預設true
        xmlReport true

        //傳入需要輸出文字報告的的檔案
        textOutput
        //是否輸出文不報告 預設false
        textReport false

        //是否將警告變成錯誤
        warningsAsErrors false

        //是否忽略警告 只報告錯誤
        ignoreWarnings true
        //檢查到錯誤時 是否包含錯誤的程式碼行數 預設true
        noLines true
        //是否關閉分析訊息輸出 如果是true就不會在終端中輸出分析的訊息 報告中仍然會有
        quiet true

        /**
         * 方法
         * 通過 lint --list 檢視多有id
         */
        //把id為 UnusedResources(正常為警告級別) 提到錯誤界別
        error('UnusedResources')
        //忽略 用法同上
        ignore('UnusedResources')
        //警告
        warning('UnusedResources')
        //重大錯誤
//        fatal('UnusedResources')
    }

    /**
     * 打包配置
     */
    packagingOptions{
        //pickFirsts做用是 當有重複檔案時 打包會報錯 這樣配置會使用第一個匹配的檔案打包進入apk
        // 表示當apk中有重複的META-INF目錄下有重複的LICENSE檔案時  只用第一個 這樣打包就不會報錯
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 當出現重複檔案時 合併重複的檔案 然後打包入apk
        //這個是有預設值得 merges = [] 這樣會把默預設值去掉  所以我們用下面這種方式 在預設值後新增
        merge 'META-INF/LICENSE'

        //排除檔案 打包時排除匹配檔案 也是有預設值得
        exclude 'META-INF/LICENSE'
    }

    /**
     * 分包規則
     * 根據cpu架構和螢幕畫素密度分包
     */
    splits{

        //cpu架構配置
        abi{
            //開啟abi分包
            enable true

            //是否建立一個包含所有有效動態庫的apk
            universalApk true

            //清空所有預設值
            reset()

            //打出包含的包 這個是和預設值累加的
            include 'x86','armeabi'

            //排除指定的cpu架構
            exclude 'mips'
        }

        //根據手機螢幕畫素密度打包
        density {
            //開啟abi分包
            enable true

            //清空所有預設值
            reset()

            //打出包含的包 這個是和預設值累加的
            include 'xhdpi','xxhdpi'

            //排除指定
            exclude 'mdpi'
        }
    }

    /**
     * 測試配置
     * 在命令列輸入 gradle :app:tDUT 可以進行測試 並輸出測試報告
     */
    testOptions{
        //在裝置化測試的時候關閉動畫 裝置化測試在androidTest裡進行  test下的是單元測試
        animationsDisabled true

        //配置單元測試
        //詳細說明見https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/Test.html
        unitTests.all {

            // 設定測試時候的一些屬性 下面這樣在ExampleUnitTest類裡寫 可以獲取value這個值
            // System.out.println(System.getProperty("key"));
            systemProperty 'key','value'

            //開啟測試的標準輸出  在命令列能夠看到輸出資訊
            testLogging.showStandardStreams = true

            //排除對應包下的所有程式碼 只能排除包 不能單獨排除類
            //下面是排除com.lin.test包下的所有測試程式碼
            exclude 'com/lin/test'
        }
    }

    /**
     * applicationVariants 獲取所有變體
     * 遍歷工程的所有變體
     *
     */
    applicationVariants.all{
        //會輸出release、debug、hello
        println it.name
        //會輸出apk的目錄 ../../../debug.apk  outputs是個集合 所以用outputs* 展開操作符去遍歷
        println it.outputs*.outputFile
    }
}

/**
 * 自定義dependencies過濾組
 * 因為dependencies只支援基本的風味分組 比如free x86 arm等 不支援組合
 * 這樣定義後就支援組合了
 */
configurations{
    freeArmDebugCompile{}
}

dependencies {
    freeArmDebugCompile 'pub.devrel:easypermissions:0.1.9'
    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:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    //匯入myLibrary庫 並指定配置為release 配和下面補充的第二條  ,
    compile project(path:':mylibrary',configuration:'release')
}

/**
 * 最後補充 都是在library庫中的gradle配置
 * 1、consumerProguardFile 'proguard-rules.pro'
 * 這個是配置到library工程裡的 defaultConfig中 意思是將library中的混淆檔案新增到主工程當中
 * 主要是給library工程新增防混淆的proguard-rules.pro檔案
 *
 * 2、publishNonDefault true  是否需要釋出所有的依賴配置
 * 我們在引入library工程時 是可以指定library的變體的 指定是release還是debug
 * 這個引數等於true的意思是 庫工程會生成多個配置 不僅僅是default的配置 這樣我們就可以
 * 指定release變體了  不然的話會報錯
 */

相關文章