android studio 的gradle 詳細配置說明

通過這篇文章,你可以簡單實現多渠道,或者說定製化的apk打包,實現一次打包多個apk,充分了解gradle的各項配置,解決資源衝突問題。

 

as 的gradle配置主要分爲三種:

1、項目全局配置的build.gradle

2、每個moudle 下的build.gradle

3、自定義的xxx.gradle (xxx爲自定義文件名)

下面對這些配置進行逐一講解

自定義xxx.gradle

在項目目錄下新建一個config.gradle文件(名字自定義)
/**
 * 自定義參數,必須爲ext ,因爲該字段爲gradle默認的擴展屬性配置
 *
 * 使用:
 * 在需要引用該文件的moudle/build.gradle 頂部輸入:apply from: "config.gradle"
 * 這條命令指明把這個config.gradle 的配置加載到當前gradle配置中,如果在項目的build.gradle
 * 引入,則該配置爲全局配置,可在項目中任意moudle的gradle中使用。
 *
 * 引用自定義的值:
 * 在moudle中引入:${"project.ext.android.versionName"}
 * 在項目moudle中引入:${"rootProject.ext.android.versionName"}
 *
 * 注意:
 * 引用時要使用雙引號,單引號不會解釋變量,直接作爲字符串,雙引號纔會解釋變量
 * println("${project.ext.android.versionCode}")輸出:1
 * println('${project.ext.android.versionCode}')輸出:${project.ext.android.versionCode}
 *
 * def修飾的對象無法在當前文件外引用
 *
 * 使用這種方式配置項目,方便項目的遷移,或者各個moudle的統一引用,最重要的是B格高
 *
 */

ext{

    android = [
            compileSdkVersion: 26,
            buildToolsVersion: '27.0.3',
            applicationId    : "com.dzt.launchmode",
            minSdkVersion    : 15,
            targetSdkVersion : 26,
            versionCode      : 1,
            versionName      : "1.0"
    ]
    //只能內部使用
    def dependVersion = [
            support    : "26.+",
            retrofit   : "2.1.0",
            butterknife: "8.4.0",
            blockcanary: "1.2.1",
            leakcanary : "1.4-beta2"
    ]

    dependencies = [
            "appcompat-v7"                   : "com.android.support:appcompat-v7:${dependVersion.support}",
            "recyclerview-v7"                : "com.android.support:recyclerview-v7:${dependVersion.support}",
            "design"                         : "com.android.support:design:${dependVersion.support}",
      ]

}

項目build.gradle配置

//該配置用於引入自定義的gradle配置文件
apply from:'config.gradle'
//buildScript是用來加載gradle腳本自身需要使用的資源,可以聲明的資源包括依賴項、第三方插件、maven倉庫地址等
buildscript {
    //指定倉庫地址
    repositories {
        //google倉庫
        google()
        //maven的中心倉庫
        jcenter()

    }
    //依賴庫
    dependencies {
//        classpath一般是添加buildscript本身需要運行的東西
        classpath 'com.android.tools.build:gradle:3.6.3'
        //接入firebasse
//        classpath 'com.google.gms:google-services:4.3.3'
//        classpath 'com.kezong:fat-aar:1.2.11'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
//配置工程所需倉庫、依賴項
allprojects {
    repositories {
        google()
        jcenter()
        //本地倉庫(默認用戶名/.m2/repository)
//        mavenLocal()
        //指定倉庫地址
//        maven { url 'D://Users/maven' }
    }
}
//事務,可以自定義,這裏是清除build目錄緩存
task clean(type: Delete) {
    delete rootProject.buildDir
}

//自定義參數,和config.gradle配置一樣
//ext {
//    compileSdkVersion = 28
//    supportLibVersion = "28.0.0"
//}

moudle下的build.gradle配置

//該配置指明該moudle是一個library庫,不是一個應用庫
apply plugin: 'com.android.library'
//該配置用於引入自定義的gradle配置文件
//apply from: "../config.gradle"

//該moudle的編譯環境,參數配置
android {
    //指定編譯的版本
    compileSdkVersion 26
    //指定構建版本
    buildToolsVersion "29.0.2"
    //示例引用自定義的值
//    buildToolsVersion ${"rootProject.ext.android.buildToolsVersion"}


    defaultConfig {
        //指定apk最低支持的os版本
        minSdkVersion 19
        //指定apk目標運行版本
        targetSdkVersion 26
        //開發版本號
        versionCode 2
        //用戶能看到的版本號
        versionName "1.0.2"

        //開啓分包(當方法數超過時會生成多個dex)
//        multiDexEnabled true

        //指定打包時添加的so庫版本
//        ndk {
//            abiFilters "armeabi", "armeabi-v7a", "x86"
//        }
    }

    //簽名配置
    signingConfigs {
        //release只是一個名稱,可自定義
        release {
            //簽名別名
            keyAlias 'test'
            //別名密碼
            keyPassword 'test12'
            //簽名文件
            storeFile file('../test.jks')
            //簽名密碼
            storePassword 'test12'
            //是否使用v2簽名
            v2SigningEnabled false  //禁用v2簽名
        }
        debug {
            //簽名別名
            keyAlias 'test'
            //別名密碼
            keyPassword 'test12'
            //簽名文件
            storeFile file('../test.jks')
            //簽名密碼
            storePassword 'test12'
            //是否使用v2簽名
            v2SigningEnabled false  //禁用v2簽名
        }

        test {
            //簽名別名
            keyAlias 'test'
            //別名密碼
            keyPassword 'test12'
            //簽名文件
            storeFile file('../test.jks')
            //簽名密碼
            storePassword 'test12'
            //是否使用v2簽名
            v2SigningEnabled false  //禁用v2簽名
        }
    }

    //構建類型配置(必須在signingConfigs配置後面)
    buildTypes {
        release {
            //啓用資源優化壓縮
//            shrinkResources true
//            //啓用代碼優化
//            minifyEnabled true
            //指定使用哪個簽名配置
            signingConfig signingConfigs.release
            //啓用代碼混淆 proguard-android-optimize.txt:爲基本混淆配置默認即可,proguard-rules.pro:擴展混淆配置
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        mytest {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

//    維度,一維(值可自定義,維度也可自定義,用,分隔開,可以自定構建apk,實現打包多個apk,差異化打包apk)
//    flavorDimensions "flavor"
//    二維(值可自定義,維度也可自定義,用,分隔開)
    flavorDimensions "modelA", "modelB"

    /**
     * 參考文檔:https://juejin.im/entry/5a586bfaf265da3e2c3808c5
     * 上面定義兩個維度,modelA,modelB,下面就通過這兩個維度配置差異化apk
     * 配置好productFlavors後,項目編譯時會生成四個apk
     * demoAtestADebug
     * demoAtestARelease
     * demoBtestADebug
     * demoBtestARelease
     * 由此可見編譯時會把你所有配置的維度組合打包各種差異化的apk
     */
    productFlavors {
        demoA {
            //配置使用哪個維度
            dimension "modelA"
            //配置差異化信息
            applicationId "com.ckj.myapplication1"
            versionCode 1
            versionName "1.0"
            /**
             * 定義佔位符,可以androidmanifest.xml中使用:
             *                 <meta-data
             *         android:name="UMENG_CHANNEL"
             *         android:value="${UMENG_CHANNEL_VALUE}" />
             */
            manifestPlaceholders = [UMENG_CHANNEL_VALUE:"value1"]
        }
        demoB {
            dimension "modelA"
            /**
             * 自定義常亮值,添加完後同步下Gradle就可以在編譯生成目錄
             * (app/build/generated/source/buildConfig)下的BuildConfig.java
             * 參數代表意義:數據類型、鍵、值
             */
            buildConfigField "boolean", "SUPPORT_AUTO_UPDATE_FEATURE", "false"
        }
        testA {
            dimension "modelB"
        }

    }
    /**
     * demoA上面是配置版本,參數信息,sourceSets是配置代碼,資源(aidl、assets、res、jni...)信息
     */
    sourceSets {
        //main是默認source
        main {
            jniLibs.srcDirs = ['libs']
        }

        //這個demoA需要在productFlavors中配置
        demoA{
            /**
             * 需要在src新建一個model/java
             * 注意:main目錄下的代碼是會和model/java下的代碼合併打包到apk的
             * 並不是只打包model/java,所以model/java只適合存放差異化代碼,這個目錄是可自定義的
             */
            java.srcDirs('src/model/java')
            //需要在src新建一個model/assets
            assets.srcDirs('src/model/assets')
            //類推
            aidl.srcDirs('src/model/aidl')
            res.srcDirs('src/model/res')
            jniLibs.srcDirs('src/model/libs')

        }

    }

    /**
     * 也是從不同維度切分apk,使apk體積縮小
     * 參考文檔:https://juejin.im/post/5ddfe513e51d45027e2a7e96
     */
    splits {
        //根據像素切分
        density {
            //是否開啓切分
            enable true
            //去掉這些像素,只打包其他尺寸apk,例如:hdpi_apk,xxhdpi_apk...
            exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
        }
        //根據架構切分
        abi {
            enable true
            exclude 'x86','arm64-v8a'
            // 重置包含的目錄,因爲已經是包含全部
            reset()
            // 設置包含,只打包這些架構的apk,調用前需要先用 reset 將默認清除
            include 'armeabi-v7a', 'x86'
            // 是否打出包含全部的apk,包含全部架構的apk
            universalApk true
        }
        //根據語言切分
        language {
            enable = true
            //同理:include包含,exclude:剔除
            include "fr", "zh", "en"
        }
    }

}
//倉庫
repositories {
    flatDir {
        dirs 'libs'   // aar目錄
    }
}

/**
 * 添加依賴有兩種方式:api、implementation
 * api:如果其他moudle引用了該moudle,則其他moudle也可以使用該moudle的依賴庫
 * implementation:其他moudle無法使用該moudle的依賴庫
 *
 * 注:gradle引用遠程庫,如果存在相同庫,默認會引入高版本的
 * 所以出現版本衝突都是和本地庫的衝突,解決方式是刪除本地庫,或者剔除遠程庫
 */

//該moudle的依賴配置
dependencies {
    //把一個文件夾裏的所有.jar文件都添加進來,可減少本地庫的逐個依賴配置
    api fileTree(include: ['*.jar'], dir: 'libs')
    //引入一個moudle
    api project(':overseas')
    //引入一個遠程第三方庫
    api('com.squareup.retrofit2:retrofit:2.2.0')
    //引入本地庫,注意是帶有files的
    api files('alipaysdk_15.7.3.jar','gson-2.5.jar')

    //引用本地aar,name:庫名 ext:庫類型(同時需要制定aar的存放路徑,具體參考上面的倉庫配置repositories)
    api(name: 'zbar-core', ext: 'aar')

    //引入一個遠程第三方庫
    implementation ('com.squareup.retrofit2:retrofit:2.2.0'){
        /**
         * exclude用來剔除傳遞依賴的庫
         * 示例解釋:
         * group:代表依賴庫的組,一個組可以有多個module(分支)
         * module:代表這個組下面的某個分支
         * 如果不填寫moudle,就會把整個group都剔除,所以需要根據實際情況剔除
         */
        exclude(group:'com.squareup.okio',module:'okio')
    }

    implementation ('com.android.support:appcompat-v7:26.0.0') {
        /**
         * 不指定group,gralde會默認使用引用庫的group
         * 如下:group=com.android.support
         */
        exclude (module: 'support-v4')
    }

    //效果等同:implementation 'com.android.support:multidex:1.0.1'
    implementation group: 'com.android.support', name: 'multidex', version: '1.0.1'

    //只有在構建demoA時纔會引入該庫
    demoAApi('com.squareup.retrofit2:retrofit:2.2.0')
    //只有在構建demoB時才引入該庫(語法:構建類型demoA(在productFlavors中的配置)+Api(或Implementation))
    demoBApi files('alipaysdk_15.7.3.jar','gson-2.5.jar')

}

//自定任務,這裏是打包一個jar包
task makeJar(type: Copy) {
    //打印信息
    println("core_${project.ext.android.versionCode}.jar")
    from('build/intermediates/aar_main_jar/debug/classes.jar', configurations.compile)
    into('build/outputs/jar')
    rename('classes.jar', "core_${project.ext.android.versionCode}.jar")
}
//把這個任務添加到build之後, 先執行build,再執行該任務
makeJar.dependsOn(build)

如有錯誤還請大神指出,謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章