大家在平时的项目里一定会被gradle困扰过,那么今天本人带大家初步解析下gradle主要内容,保证我们能正常操作代码,不会被困惑。在gradle里面,从上到下介绍(在我的demo项目里面),分别是defaultConfig{},signingConfigs{},buildTypes{},productFlavors{},首先是defaultConfig{},默认情况下这个里面的信息是
defaultConfig{
applicationId "com.example.liangxingguo.demo"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
也就是一些版本号,但是如果稍微有些规模的话,applicationId是不会放到这里面的,这个后面我们会介绍到,然后是signingConfigs{},这个里面会定义数个type,比如
signingConfigs{
debug{
storeFile file("../debug.keystore")
storePassword "3333"
keyAlias "signdebugkey"
keyPassword "3333"
}
release{}
}
当然type的名字是我们自己随便定义的,debug下的内容大部分就是上面贴的东西,因为dubug模式下数据是不怕暴露的,但是release情况下,这些数据时不应该暴露出来的,我们得间接的去调用,一般是如下情况
//这是demo1
release {
def Properties localProps = new Properties()
localProps.load(new FileInputStream(file('../local.properties')))
def Properties keyProps = new Properties()
if (localProps['keystore.props.file'] != null) {
keyProps.load(new FileInputStream(file(localProps['keystore.props.file'])))
}
storeFile keyProps["store.file"] != null ? file(keyProps["store.file"]) : null
keyAlias keyProps["key.alias"] ?: ""
storePassword keyProps["store.password"] ?: ""
keyPassword keyProps["key.password"] ?: ""
}
-------------------------------------------------------
//这是demo2
release {
//加载资源
Properties properties = new Properties()
InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream() ;
properties.load( inputStream )
//读取文件
def sdkDir = properties.getProperty('key.file')
storeFile file( sdkDir )
//读取字段
def key_keyAlias = properties.getProperty( 'keyAlias' )
def key_keyPassword = properties.getProperty( 'keyPassword' ) ;
def key_storePassword = properties.getProperty( 'storePassword' ) ;
storePassword key_storePassword
keyAlias key_keyAlias
keyPassword key_keyPassword }
如上,需要我们在项目里的local.properties配置,基本上都是大同小异,但是据本人的细微观察,得到文件中的属性有两种方式,一个是demo1下的keyProps["key.alias"],Properties对象后中括号,然后括号里面直接是属性名,另一种是demo2的,即properties.getProperty( 'keyAlias' ),哪种都行,但是本人之前一直有一个疑问,就是本人在打正式包时,一直是这样的步骤,Build->Generate Sign Buid->配置各种签名->打包,在这个步骤里面,好像并没有用到我们gradle里面的配置,因为它直接让我们又重新配置的签名,如下
那么什么时候才会用到我们gradle里面的签名配置呢,有以下情况会用到
first:当我们点击AndroidStudio左下角的BuildVariants后选择环境(如下图),这的这个环境和我们在gradle里面配的buildType和productFlavors有关,但只要选择带有release的坏境即可,选好环境之后,直接点击Build下的Build APK就会用到我们的配置
second:点击AndroidStudio右上角的Gradle,选择assembleRelease,用gradle脚本直接打包也可以用到我们的gradle配置
ok,下面我们来介绍第三块内容buildTypes{},依然先看本人demo的例子,如下
buildTypes {
debug { //类型名字也是自取
signingConfig signingConfigs.debug //调用signingConfig里debug的配置
}
release { //类型名字也是自取
minifyEnabled true //是否混淆
shrinkResources true //是否放弃一些没有用到的res下的资源
signingConfig signingConfigs.release //调用signingConfig里的elease配置
proguardFiles 'proguard-rules.pro', getDefaultProguardFile('proguard-android.txt') //混淆时使用的sdk下的文件配置,具体可以浏览Android Proguard工具使用和配置详解_ccpat的博客-CSDN博客_proguard-android-optimize.txt
}
//下面是修改生成的apk名字的方式,前三行都是固定模式,如果想要修改apk名字,可以修改appName等属性
applicationVariants.all { variant ->
if (variant.buildType.name.equals('release')) {
variant.outputs.each { output ->
def appName = 'MyApp'
def oldFile = output.outputFile
def buildName
def releaseApkName
variant.productFlavors.each { product -> buildName = product.name }
releaseApkName = appName + getVersionNameFromManifest() + '-' + buildName + '-' + getDate() + '.apk'
output.outputFile = new File(oldFile.parent, releaseApkName) } } }
}
有此看来,buildType里面可以配置些混淆,修改apk名字等功能,接下来是productFlavors{},这个相对来说比较重要,因为很多配置都是在这里面,而且可以灵活的配置一些我们的需求,依旧先上代码,
productFlavors {
product {
applicationId "com.gradle"
}
internal {
applicationId "com.gradle.internal"
}
internal2 {
applicationId "com.gradle.internal2"
}
}
这是一个最简单的配置,也就是刚开始我们提到的灵活配置applicationId,满足我们测试包和正式包配置不同的包名,当然,此处也可以以加不同后缀的方式去配置,如下:
defaultConfig{
applicationId "com.gradle"
}
productFlavors {
product {
applicationIdSuffiex ".internal"
}
internal {
applicationIdSuffiex ".internal1"
}
internal2 {
applicationIdSuffiex ".internal2"
}
}
这样打出的包名分别是com.gradle.internal,com.gradle.internal1,com.gradle.internal2,而且,defaultConfig里面的那些配置完全可以在这里面都配置,满足我们不同版本需要不同配置,当然,一些三方的appKey等数据放在这里面再好不过了,比如你的项目里面集成了小米推送,在小米官方网站创建完应用之后,官方会给你一个appKey,需要我们在代码中注册时传进去,在集成完之后,项目上线,ok,第二版迭代开发,产品经理让你再拓展一下推送功能,完成时候你要测试,但总不能用线上的账号测试吧,你测试数据推到线上用户的账号上,会让用户喷死的,然后我们只能测试用测试的key,打正式包时用正式key,这样如果手动改来改去会很麻烦,所以productFlavors来了,我们可以这样
productFlavors {
debug{
applicationIdSuffiex ".internal"
buildConfigField "String", "MIPUSH_APPID", "\"12345\""
}
release {
applicationIdSuffiex ".internal1"
buildConfigField "String", "MIPUSH_APPID", "\"67890\""
}
}
那么我们在用的时候直接BuildConfig.MIPUSH_APPID就ok啦,那上面的例子,有dubug和release两种版本,我想这两种形式的icon不一样,可以,我们一步步来实现。首先需要我们把AndroidStudio切换为peoject形式,然后再src下面(和main目录同级)建立两个folder,名字为debug和release,然后分别在这这两个目录下建立res文件夹,然后建立相应的mitmap-hdpi等文件夹,总之就是和main下的文件路径保持一致,但是在mitmap下我们放不同的icon,这样打相应的包,icon就不一样了,上图看下本人的例子
注意,value下的文件不能这么玩哦,另一种情况,如果我们想测试包和正式包的引导页不同,也可以,走起,比如我们的引导页叫SplashActivity,那我们就在debug和release下面同时建立SplashActivity,然后里面有不同的内容,但是前提是main里面一定不要有SplashActivity,只要是另外两个文件共同出现的,main里面都不要有,他是放共同的文件的,ok,这样就优雅的实现了不同包展现不同内容
文章到最后,小编分享一个dependence里的compile和provided的区别,因为这个当时也困惑过我,compile是从repository(默认是jCenter())里下载一个依赖包进行编译并打包,而provided只提供编译支持,但是不会写入apk。比如我在编译的时候对某一个jar文件有依赖,但是最终打包apk文件时,我不想把这个jar文件放进去,可以用这个命令。什么场景下使用provided这个命令呢,比如我们的项目一般都会包括2-3和model,其中1-2个是library,如果我们在正式model里面引用了okhttp等库,然后library也需要用到,那么library里面引用时就可以用provide,这样在打包时library的okhttp就不会打进去了。
文章到这已经接近尾声,如果文中有不妥的观点,欢迎issues,大家共同进步!