Gradle 打包知识整理-Android Studio

本文详细介绍了如何在Android项目中自定义构建流程,利用utils.gradle实现公用方法处理,如获取版本信息、复制文件、清理输出目录等,并通过productFlavors实现分渠道打包。此外,文章还涵盖了构建类型、签名信息、打包文件名的定制以及如何在AndroidManifest中指定版本信息等关键步骤。
摘要由CSDN通过智能技术生成

以下内容是针对自我一天的Gradle了解所得,如有不当之处,还望指正。
关于Gradle原理之类的东西,我看了但是理解的不好,所以也就不说了。具体看参见此文。深入理解Android之Gradle

1、utils.gradle

新建了一个工具gradle,主要用于存放公用方法处理,方法大致如下:

//从AndroidManifest中获得版本名称
def getVersionName() {
    def xmlFile = project.file("src\\main\\AndroidManifest.xml")
    def rootManifest = new XmlSlurper().parse(xmlFile)
    return rootManifest['@android:versionName']
}
//从AndroidManifest中获得版本号
def getVersionCode() {
    def xmlFile = project.file("src\\main\\AndroidManifest.xml")
    def rootManifest = new XmlSlurper().parse(xmlFile)
    return rootManifest['@android:versionCode']
}
//对于 android library编译,我会 disable 所有的 debug 编译任务 
def disableDebugBuild() {
    //project.tasks 包含了所有的 tasks,下面的 findAll 是寻找那些名字中带 debug 的 Task。
   //返回值保存到 targetTasks 容器中
    def targetTasks = project.tasks.findAll { task ->
        task.name.contains("Debug")
    }
    //对满足条件的 task,设置它为 disable。如此这般,这个 Task 就不会被执行
    targetTasks.each {
        println "disable debug task  : ${it.name}"
        it.setEnabled false
    }
}
//获取当前系统的时间
def releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}

//文件复制
def copyFile(File srcFile, File targetFile) {
    targetFile.withOutputStream { os ->
        srcFile.withInputStream { ins ->
            os << ins
        }
    }
}

//清理输出目录
def cleanOutPut() {
    File outputFile = new File("app\\build\\outputs\\apk")
    if (outputFile.exists() && outputFile.isDirectory()) {
        outputFile.deleteDir()
    }
}

//将函数设置为 extra 属性中去,这样,加载 utils.gradle 的 Project 就能调用此文件中定义的函数了 
ext {
    getVersionCode = this.&getVersionCode
    getVersionName = this.&getVersionName
    disableDebugBuild = this.&disableDebugBuild
    releaseTime = this.&releaseTime
    copyFile = this.&copyFile
    cleanOutPut = this.&cleanOutPut
} 

2、在所有项目中使用utils.gradle

在主项目(并非app module)的build.gradle添加如下代码。

buildscript {
    ....
}

//遍历所有项目,包括当前主项目
allprojects {
    repositories {
        jcenter()
    }
}

//遍历所有子项目(module)
subprojects {
    //为每个子 Project 加载 utils.gradle 。当然,这句话可以放到 buildscript 花括号之后
    apply from: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"
}

3、分渠道打包

3.1 在app module的AndroidManifest.xml中定义好 “占位符”
<meta-data
    android:name="UMENG_CHANNEL"
    android:value="${CHANNEL_VALUE}" />

<meta-data
    android:name="CHANNEL_ID"
    android:value="${CHANNEL_ID}" />
3.2 使用productFlavors列举所有待打包的渠道信息
productFlavors {
    xiaomi {
        manifestPlaceholders = [CHANNEL_VALUE: 'xiaomi', CHANNEL_ID: 300]
    }
    suibian {
        manifestPlaceholders = [CHANNEL_VALUE: 'suibian', CHANNEL_ID: 400]
    }
    shishi {
        manifestPlaceholders = [CHANNEL_VALUE: 'shishi', CHANNEL_ID: 200]
    }
}
3.3 指定打包时的签名信息

使用gradle打包时,他会打包成两类包,一类是签名包,另一个就是为签名包(unaligned)。
unaligned代表没有进行zip优化的,unsigned代表没有签名的
如果此处你的配置有问题,密码或者别名不对,编译就会失败,给出类似 Failed to read key from keystore的提示。

apply plugin: 'com.android.application'

android {
    ...
    signingConfigs {
        release {
            storeFile file("keyStore\\kkss.jks")
            storePassword "aaaaaa"
            keyAlias "kkssTest1"
            keyPassword "aaaaaa"
        }
        //debug包的签名信息
        debug {
            storeFile file("keyStore\\kkss.debug.jks")
            storePassword "aaaaaa"
            keyAlias "kkssDebugTest1"
            keyPassword "aaaaaa"
        }
    }
    ...
}
3.4 指定构建类型

在使用gradle构建时,可以使用assemble对所有buildType构建,也可以使用assembleRelease,assembleDebug,assembleDemo单独构建(demo为自定义字符串)。

apply plugin: 'com.android.application'

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

        debug {
            debuggable true
            minifyEnabled false//是否混淆
            signingConfig signingConfigs.debug
        }

        //定义的构建类型,用assemble打包时自动构建,也可以用assembleDemo单独构建
        demo {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    ...
}
3.5 更改打包出来的apk文件名

此步骤只会更改签名包的apk文件名

apply plugin: 'com.android.application'

android {
    ...
    //修改生成的apk名字,格式为 app名_版本号_打包时间_渠道名_buildType.apk
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def oldFile = output.outputFile
            def versionName = variant.versionName
            def releaseApkName = "appName_v" + versionName + "_${releaseTime()}_" + variant.productFlavors[0].name + '_' + variant.buildType.name + '.apk'
            output.outputFile = new File(oldFile.parent, releaseApkName)
        }
    }
    ...
}

以下是可选步骤

3.6 使用AndroidManifest中指定版本信息

在AS中一般是以gradle文件中指定的版本信息(versionCode,versionName)进行打包,但是如果你想使用AndroidManifest的版本信息的话,你可以参见以下代码。

apply plugin: 'com.android.application'

android {
    defaultConfig {
        applicationId "com.crrain.frescotest"
        minSdkVersion 10
        targetSdkVersion 23
    }
    ...
    //创建一个task,动态更新defaultConfig的版本信息的配置
    task initVersionInfoWithManifestFile {
        //这里的getVersionCode(),getVersionName()是在utils.gradle中定义的。由于我们已经为每个子项目加载了该文件,所以此处可以直接使用。
        defaultConfig.versionCode = getVersionCode().text().toInteger()
        defaultConfig.versionName = getVersionName()
    }
    ...
}
3.7 在编译时运行清理和设置版本信息Task
apply plugin: 'com.android.application'

android {
    ...
    //新建的清理输出目录的Task,该Task依赖了初始化版本信息的Task,所以会运行之。
    task cleanOutPutCash(dependsOn: initVersionInfoWithManifestFile) {
        cleanOutPut()
    }

    //指定在编译时运行清理Task
    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn cleanOutPutCash
    }
    ...
}
3.8 禁用lint自检造成的打包失败
lintOptions {
    abortOnError false
}
3.9 支持AAR包

aar是由AS打包出来的项目资源包(*.jar+res资源)。

apply plugin: 'com.android.application'

android {
    ...
    //支持AAR
    repositories {
        flatDir {
            dirs 'libs'
        }
    }
}

dependencies {
    ...
    compile(name: 'xxx', ext: 'aar')
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值