今天记录一下gradle里一些常用的操作
点击获取所有gradle版本
在project的build.gradle如下操作
ext {
// Sdk and tools
compileSdkVersion = 26
buildToolsVersion = "26.0.2"
minSdkVersion = 16
targetSdkVersion = 26
versionCode = 1
versionName = "1.0"
// support
supportVersion = '26.1.0'
// butterknife
butterknife = '8.8.1'
}
这里这个ext我其实蛮费解的,因为也没有深入的看过gradle的相关api什么的,不知道为什么必须是ext这个名字,我尝试换过名字就显示method不存在了,定义好的吗?有识之士可以帮我解答下,言归正传,定义好之后,在app以及各个module下可以这样使用
defaultConfig {
applicationId ...
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
}
依赖里可以这样,以butterknife为例,其他依赖同理
dependencies {
......
implementation "com.android.support:appcompat-v7:$rootProject.ext.supportVersion"
implementation "com.android.support:recyclerview-v7:$rootProject.ext.supportVersion"
......
implementation "com.jakewharton:butterknife:$rootProject.ext.butterknife"
annotationProcessor "com.jakewharton:butterknife-compiler:$rootProject.ext.butterknife"
}
gradle有很好用的多渠道管理,你可以在里面设置测试用的appId啊,或者不同的url根地址啊等等信息,具体如下
productFlavors {
// a渠道
aqd {
#如果这里什么都不写,会默认使用default的设置
}
// 测试渠道
ceshiqd {
// 测试版AppId
applicationId "自由定义"
// 根域名
manifestPlaceholders = [serverDomain: "http://......"]
buildConfigField("String", "serverDomain", "\"http://......\"")
}
}
注意 gradle 3.0以后,使用productFlavors需要进行如下配置
defaultConfig {
......
flavorDimensions "自定义名字"
......
}
同时这里引申出了占位符和Build.Config,这俩个哥们贼好用,具体怎么好用待我给你细细分解
我们开发过程中,经常集成一些地图啊、定位啊、统计啊,分享啊之类的地方的sdk,而这些第三方sdk往往会需要你申请一个Appkey,在官方示例中,Appkey的书写位置一般都是manifest文件下面,我们以百度统计为例,如下所示
我们写的时候一般都会将自己申请的Appkey替换到APP KEY那里,但是我们既然用了gradle来管理项目,我们有时候就不想同时维护manifest和gradle,我们的理想情况是所有的配置都在gradle里进行配置,这时候占位符的作用就出来了,我们可以这么写
然后在gradle里这么写
defaultConfig {
......
manifestPlaceholders = [ appkey : "你申请的appkey" ]
......
}
唉,就很皮,就很基础,这里注意就是你manifest里value那里的名称要和gradle里这个名称一致,对应我这里就是appkey这个名称,这是占位符的一种用法,还有一种,就是上面我讲多渠道的时候,里面有个根url,我也是用占位符写的,怎么使用的呢?看下面,同样的,首先是manifest里,在application标签下,这个不用强调吧,嘿嘿
然后,在我们自定义的Application类里,我们可以获取到这个根url进行全局使用
private void initDomain() {
//获取本应用程序信息
ApplicationInfo applicationInfo = null;
try {
applicationInfo = getPackageManager().getApplicationInfo(this.getPackageName(), PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
//读取信息
if (null != applicationInfo) {
this.serverDomain = applicationInfo.metaData.getString("serverDomain");
}
}
这样,我们就获取到了gradle里定义的serverDomain的根url,其余的用法同理,类比一下就行
这哥们很好用啊,我现在已经爱不释手了,打Log的时候,好多人推荐说是用BuildConfig.DEBUG来决定是否打印,但是我感觉这样不好用,很简单的道理,我们给测试打包的时候,很可能打的不是debug的包,但是我们也想看log,但是正式包里又不想了,这时候BuildConfig.DEBUG就不太好用了,我是这样做的
defaultConfig {
......
buildConfigField("boolean", "isBeta", "false")
......
}
productFlavors {
// 正式站
zs {
}
// 测试站
cs {
......
buildConfigField("boolean", "isBeta", "true")
......
}
}
正式站的时候,会默认使用defaultConfig里的配置,然后编译好以后,是这样的
public final class BuildConfig {
......
public static final boolean isBeta = true;// 如果是正式,这里是false
......
}
这样,我就保证了所有测试包isBeta就是true,所有的正式包isBeta都是false,就可以用这个字段来进行所有区分正式测试的操作,包括是否打印log、是否上传统计数据等等,同时,Build.Config也可以胜任配置根url的工作,而且比占位符更爽,以我上面代码为例,唯一需要注意的就是链接的双引号需要进行转义,看我代码里的写法即可,其余的用法和isBeta同理,所有的基本类型和String都可以在gradle里进行配置,具体用法可以自由拓展。
这个就很简单了,直接看代码
defaultConfig {
......
//打包文件名
applicationVariants.all { variant ->
variant.outputs.all { output ->
if (outputFileName.endsWith('.apk')) {
//这里只区分测试正式,你可以多进行区分,各个节点都可以
if (outputFileName.contains("cs")) {
outputFileName = "自定义测试.apk"
} else {
// 我这里多加了一个版本号来进行命名,方便后期区分
outputFileName = "自定义正式_${defaultConfig.versionName}.apk"
}
}
// 这个自定义路径,目录变为根目录/apk这样,想更改可以自由拓展
variant.packageApplication.outputDirectory = new File("./apk")
}
}
}
我这里只判断了测试和正式的节点,就是contains(“cs”)这里,你可以用你项目里多渠道那个名称或者debug啊之类的节点来区分打不同名称的包,都是可以的
这个我目前采用的是exclude的方法 代码如下
compile ('.....') {
exclude group: 'com.android.support'
}
这种操作是排除了com.android.support这个group下的所有依赖,也可以更精确一点
compile ('.....') {
exclude group: 'com.android.support' , module: 'appcompat-v7'
}
这种操作是排除com.android.support这个组下特定module比如appcompat-v7这样,其他的依次类比拓展即可
现在升级到gradle3.0以后,关键字发生了变化,原来的compile 是现在的api,不管是compile还是api,这个关键字会暴露依赖里的方法,简单来说假设A依赖B,B依赖C,都是用compile或api关键字依赖,那么A就可以使用C的方法,gradle3.0以后,有个关键字是implementation,这个关键字就不可以,所以我猜想,版本冲突的时候是不是可以用implementation依赖来避免,有待验证,有验证过的哥们可以回复下哈
哈哈,这个就是我首先发所有gradle版本链接的目的所在啦,有时候我们打开一个项目,假设用了gradle4.1,但是我们本地没有,这时候studio就会一直下载,不FQ下载又慢的不行不行的,运气不好几个小时过去还在downloading,其实我们完全没必要这样,你可以从我最上面那个链接里离线下载一个你需要的gradle版本,以4.5为例
下载红框内的这个 all.zip这样的, 这个下载是很快的,下载好之后放哪里呢?你studio自动下载的时候会生成一个乱码的目录,这个有可能你配置过gradle目录,那就以你的为准,我的目录是c盘,如图所示,你可以自己类比你的路径
进入这个乱码目录以后,把studio自动下载的那些彻底删除就好,不用害怕,然后把你下载好的gradle-4.5-all.zip这个文件粘贴进去就OK,然后重新启动studio,你会惊喜的发现,downloading过程一闪而过,哈哈哈哈,切记,这个zip文件必须放到由studio自己下载生成的那个乱码目录里,别自己写个目录,也别自己解压zip文件,你粘贴进去以后别管,重启studio会自动给你解压的,多说几句,我们开发时候,gradle版本其实没必要总是用最新的,我们可以下载配置好一个以后,其余所有项目都用这个gradle,直接避免每次下载的烦恼,那么怎么配置呢,看图即可
根据步骤1234即可,注意红框内的路径,一定要选到你gradle目录所需版本最里面乱码目录里面的真正目录下为止,这样可以避免每次下载的问题。