湖畔镇

Gradle相关资料

本文罗列一些Gradle的资料

深入理解Gradle

这篇文章是从API的角度做的教程,可以更清楚的了解Gradle

Gradle脚本基础全攻略

这个基本就是官方文档的翻译版,讲述了实现一些特性的方法

Groovy脚本基础全攻略

Gradle是基于Groovy的DSL,可以通过这篇文章简单学习一下,更多参见Groovy官方网站

Gradle User Guide

很详细的用户指南,就是看起来比较累

Gradle API

Gradle的API手册

Gradle DSL

Gradle的DSL,差不多脚本块里面会用到的东西都可以这里查

Gradle Android DSL

Gradle Android插件的DSL

一个模板脚本

提供了很多特性,可以参考和直接使用,参见Gradle Tips and Recipes

apply plugin: 'com.android.application'

//  配置阶段清空结果文件夹
def init() {
    def outputDir = new File(project.rootDir, 'output')
    outputDir.listFiles().each {
        it.delete()
    }
}
init()

//  只能写为顶层工程的属性
rootProject.ext {
    compileSdkVersion = 25
}

android {
    //  访问工程范围的属性
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion "25.0.2"

    defaultConfig {
        applicationId "lakeshire.gitlab.com.myapplication"
        minSdkVersion 14
        targetSdkVersion 25

        //  manifest可以使用这些
        def filesAuthorityValue = applicationId + '.files'
        manifestPlaceholders = [ filesAuthority : filesAuthorityValue ]

        //  标识版本
        versionCode 1
        //  用户可见的版本号
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        //  发布版的签名配置
        release {
            storeFile file("../my-release-key.jks")
            storePassword "password"
            keyAlias "alias"
            keyPassword "password"
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    //  指定两个产品风味的维度
    flavorDimensions 'mode', 'api'

    productFlavors {
        free {
            dimension 'mode'
            versionNameSuffix '-free'
        }
        pay {
            dimension 'mode'
            versionNameSuffix '-pay'
        }
        minApi24 {
            dimension "api"
            minSdkVersion '24'
            versionCode 30000 + android.defaultConfig.versionCode
            versionNameSuffix "-minApi24"
        }
        minApi21 {
            dimension "api"
            minSdkVersion '21'
            versionCode 10000  + android.defaultConfig.versionCode
            versionNameSuffix "-minApi21"
        }
    }

    sourceSets {
        //  改变文件的位置
        main {
            java.srcDirs = ['other/java']
            //  不能包含冲突的文件
            res.srcDirs = ['src/other/res']
            manifest.srcFile 'src/main/AndroidManifest.xml'
            //  最常见的Eclipse工程转化为AS工程SO文件在这里找
            jniLibs.srcDirs = ['libs']
        }

        androidTest {
            setRoot 'src/tests'
        }
    }

    //  产生分离的apk 可用来减小安装包 对应的包只包含相关的资源什么的
    splits {
        density {
            enable true
            exclude "ldpi", "mdpi"
            //  默认是排除,也可以先清理再包括
            //  reset()
            //  include "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"
            compatibleScreens 'normal', 'large', 'xlarge'
        }

        abi {
            enable true
            //  默认所有ABI都包括,清理
            reset()
            include "x86", "armeabi-v7a", "mips"
            //  需要生成一个包括所有ABI的APK
            universalApk true
        }
    }

    //  过滤变体
    variantFilter { variant ->
        def names = variant.flavors*.name
        if (names.contains("minApi21") || names.contains("free")) {
            setIgnore(true)
        }
    }

    dexOptions {
        maxProcessCount 8
        javaMaxHeapSize "2g"
        preDexLibraries true
    }
}

dependencies {
    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.1.1'
    compile 'com.android.support:design:25.1.1'
    testCompile 'junit:junit:4.12'
    //  本地模块
    compile project(':mylibrary')
    //  AAR
    compile(name: 'play-services-7.8.87', ext: 'aar')
}

//  对每个变体 找出对应任务 在任务完成后拷贝安装包到最终目录
afterEvaluate {
    project.android.applicationVariants.each { variant ->
        def assembleTaskName = "assemble${variant.name.capitalize()}"
        def assembleTask = project.tasks.findByName(assembleTaskName)
        if (assembleTask != null) {
            assembleTask.doLast {
                copyApk(variant)
            }
        }
    }
}

//  拷贝安装包 只拷贝release版本 并重命名
def copyApk(def variant) {
    variant.outputs.each { output ->
        if (output.outputFile.name.contains('release') && output.outputFile.name.endsWith('apk')) {
            println '================ Copy Release APK ================'
            println output.outputFile.name
            def time = new Date().format("yyyyMMddHHmmss")
            def mainName = output.outputFile.name.split("\\.")[0]
            def dstName =  mainName + '-' + output.versionCode + '-' + time + '.apk'
            def src = output.outputFile
            def dst = new File("${project.rootDir}/output", dstName)
            dst.withOutputStream { os ->
                src.withOutputStream { is ->
                    os << is
                }
            }
        }
    }
}
分享