博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
项目实战之gradle在实际项目中的使用
阅读量:6031 次
发布时间:2019-06-20

本文共 6656 字,大约阅读时间需要 22 分钟。

前言

本文作为实战系列,主要讲解gradle在实际项目中的使用,原理部分不会讲解太多。本文会用到一些Groovy的知识,如果不了解Groovy基础语法的话可以参考一下主席的文章,。当然我也会对使用到的地方做注解说明,就算你不看的话,也行。

1、统一依赖管理

这里主要是说项目的编译版本、依赖库的版本等,这里参考Google官方的项目,在项目的根目录单独建一个version.gradle文件统一管理版本,这样做的好处明显,特别是多module的项目,很方便的做统一版本管理,避免冲突。但是这样做也会带来一个坏处,就是你inspection检查新版本的时候,当有了新版本的话,你是检查不到的。不过总体来说,利大于弊吧。

来看一看version.gradle文件里都有些什么吧

// version.gradle文件ext{android = [        compileSdkVersion: 27,        minSdkVersion    : 21,        targetSdkVersion : 27,        versionName: "1.0.0"    ]dependencies = [        appcompatV7 : 'com.android.support:appcompat-v7:27.1.1',        design      : 'com.android.support:design:27.1.1',        constrant :'com.android.support.constraint:constraint-layout:1.0.2'    ]}复制代码

这里作为说明,只写了几个最基本的依赖,接下来就是要使用这些配置了。首先在project的build.gradle文件里引入

buildscript {    apply from: 'version.gradle'    repositories {        google()        jcenter()    }    …………}复制代码

然后,在module的gradle里就可以愉快的使用了。

compileSdkVersion rootProject.ext.android.compileSdkVersiondefaultConfig {    minSdkVersion rootProject.ext.android.minSdkVersion    targetSdkVersion rootProject.ext.android.targetSdkVersion    versionCode getCode()    versionName rootProject.ext.android.versionName    …………}dependencies {    implementation fileTree(include: ['*.jar'], dir: 'libs')    implementation rootProject.ext.dependencies.appcompatV7    implementation rootProject.ext.dependencies.constrant    implementation rootProject.ext.dependencies.design    testImplementation 'junit:junit:4.12'    androidTestImplementation 'com.android.support.test:runner:1.0.1'    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'}复制代码

2、根据versionName 自动生成versionCode

细心的小伙伴可能发现了,上面的versionCode并没有使用version.gradle里配置的versionCode,事实上version.gradle里也并没有配置versionCode,这里我是根据产品需求使用versionName自动生成的versionCode。

// 读取version.gradle里的versionName 生成versionCodedef getCode() {    String name = rootProject.ext.android.versionName    List arr = name.tokenize('.')    int code1    int code2    int code3    code1 = arr.get(0).toInteger() * 10000    code2 = arr.get(1).toInteger() * 100    code3 = arr.get(2).toInteger()    int code = code1 + code2 + code3}复制代码

上面就是获取版本号的方法,采用三段式,每段两位,可以根据实际需求自己改。另外说明一下,Groovy语法里,如果自己不写return语句,会把最后一行计算的code自动return。这样的话,就不用每次版本升级要修改versionName还要修改versionCode了。注意上面的代码是在android的同级领域。

3、优雅的签名设置

签名文件怎么生成这里就不说了,需要说明的是为了方便引用,jks签名文件我放在了app目录下,同样在这个目录下,创建了一个signing.properties的文件,文件内容如下:

// signing.properties 文件storePass=123456alias=keykeyPass=123456v2SigningEnabled=falsesigningFile=key.jks复制代码

就是基本的签名信息了,看一下module的gradle里的使用:

signingConfigs {    // 定义signConfig并赋值    signConfig    File propFile = file('signing.properties')    if (propFile.exists()) {        Properties props = new Properties()        props.load(new FileInputStream(propFile))        if (props.containsKey('signingFile') && props.containsKey('storePass') &&                props.containsKey('alias') && props.containsKey('keyPass') && props.containsKey("v2SigningEnabled")) {            signConfig.storeFile = file(props['signingFile'])            signConfig.storePassword = props['storePass']            signConfig.keyAlias = props['alias']            signConfig.keyPassword = props['keyPass']            android.signingConfigs.signConfig.v2SigningEnabled = props['v2SigningEnabled']        } else {            android.buildTypes.release.signingConfig = null            android.buildTypes.flavor.signingConfig = null        }    } else {        android.buildTypes.release.signingConfig = null        android.buildTypes.flavor.signingConfig = null    }    print("signingConfigs===========${signConfig}")}复制代码

就是定义一个signConfig 并给赋值了,很简单。但是这样写就避免了直接在gradle里暴露签名信息了。当然你可以在terminal里运行一下gradle guild指令来验证,看一下打印结果是否正确。

配置完以后,直接在buildTypes里引用就行了。

release {        minifyEnabled false        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        signingConfig signingConfigs.signConfig        …………    }复制代码

4、自定义BuildConfig

实际开发中服务器一般有正式环境和生成环境,有时候还会有个后台开发人员自己本地的服务器环境,这时候通过自定义buildConfigField来区分配置不同的环境

release {        minifyEnabled false        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        signingConfig signingConfigs.signConfig        buildConfigField "boolean","isRelease","true"        …………    }复制代码

我们在release的type里把值设置为true,其他的type设置为fasle,这样,同步完以后,在BuildConfig类里会多出一个静态变量isRelease,这样在java代码里,就可以根据这个变量来判断是测试环境还是生产环境了,还可以根据这个变量来控制是否需要日志输出等。甚至你都可以直接把测试服务器地址和生产服务器地址配置到里面都行。

buildConfigField 'String','API_SERVER_URL','"http://lxy.v1/"'复制代码

5、不同的版本配置不同的包名和AppName

实际开发中,为了区分测试版和正式版,有时候需要把测试版的包名和app名字设置为不同。其实这样的需求用gradle分分钟就可以实现

release {        minifyEnabled false        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        signingConfig signingConfigs.signConfig        buildConfigField "boolean","isFlavor","false"        manifestPlaceholders = [                APP_NAME           : "release"        ]    }    debug {        minifyEnabled false        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        signingConfig signingConfigs.signConfig        buildConfigField "boolean","isFlavor","false"        applicationIdSuffix 'debug'        manifestPlaceholders = [                APP_NAME           : "debug"        ]    }复制代码

如上,在debug版里,配置了applicationIdSuffix 'debug',这样打包的话,会在原来的包名后面加上debug,这样安装到手机上就是两个不同的app了,因为包名不同。这样一个测试机就可以同时测试测试包和正式包了。而且,还设置了manifestPlaceholders占位符,这样在menifests文件里直接引用就行,就实现了不同的包名和app名字。

// 清单文件里引用android:label="${APP_NAME}"复制代码

这里有个坑,如果这样配置过后,如果你项目里使用有微信支付、分享等的sdk,注意支付、分享后的回调的类所在的包和正式版分开,否则是收不到回调的(微信的sdk有时候很蛋疼)。

6、自定义打包apk的文件名

在android的领域里添加如下代码

applicationVariants.all { variant ->    variant.outputs.all { output ->        def newApkName        newApkName = getTime() + defaultConfig.versionName + "-" + defaultConfig.versionCode + ".apk"        outputFileName = newApkName    }}复制代码

getTime()方法在android领域的同级

def getTime() {     return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}复制代码

7、java8和dataBinding的支持

java8的lambda还是很简洁的,同样,dataBinding用起来一样爽飞

// 当然在android领域里设置了  dataBinding {    enabled = true}compileOptions {    sourceCompatibility JavaVersion.VERSION_1_8    targetCompatibility JavaVersion.VERSION_1_8}复制代码

8、自定义jinlibs目录

现在新建as项目会自动在app目录下生成一个libs目录,可以在gradle里设置jar、so库等的文件目录

sourceSets {    main {        jniLibs.srcDirs = ['libs']    }}复制代码

9、混淆、多渠道打包等其他配置

混淆配置的话配置在release版本里,注意别忘了添加混淆文件

minifyEnabled truezipAlignEnabled trueshrinkResources true复制代码

用gradle打包多渠道的话比较慢,这里就不讲了,个人感觉360多渠道打包挺好用的,推荐一下。

以上是实际项目里常用的配置,当然还有很多不太常用的配置,如可能需要打包aar到maven,gradle编译、gradle性能检测、gradle加速、使用gradle缓存,自定义gradle插件等等,篇幅问题,大家自己学习了……

,如果对你有帮助,麻烦start鼓励一下!

转载地址:http://eldhx.baihongyu.com/

你可能感兴趣的文章
android学习——popupWindow 在指定位置上的显示
查看>>
把Android源代码加入SDK
查看>>
深踩 AndroidStudio 缓存的坑
查看>>
RandomAccessFile和memory-mapped files
查看>>
.NET Core采用的全新配置系统[3]: “Options模式”下的配置是如何绑定为Options对象...
查看>>
MySQL隔离级别
查看>>
URAL 1051 Simple Game on a Grid
查看>>
求时间差的sql语句。 比如如下数据
查看>>
001 有关中文乱码的处理
查看>>
NIO学习系列:核心概念及基本读写
查看>>
vc中ASSERT()和VERIFY()区别
查看>>
centOS 搭建SVN服务器,提交自动发布代码,详细教程,及注意事项
查看>>
HTML<div><span>字符实体
查看>>
CentOS6.3安装PowerVault MD Storage Manager
查看>>
HTML 表格
查看>>
VMware 虚拟化编程(7) — VixDiskLib 虚拟磁盘库详解之三
查看>>
php 未实例化类调用方法的问题
查看>>
Anaconda jupyter notebook 出现 kernel error 解决办法
查看>>
我对读计算机软件专业硕士的几点看法
查看>>
【枚举】bzoj1800 [Ahoi2009]fly 飞行棋
查看>>