赞
踩
Gradle makes the impossible possible, the possible easy and the easy elegant.
在Android开发中经常会用Gradle来构建项目,Gradle能很方便的项目的版本集成和打包,虽Gradle官方已经给出很详细的文档了,但还是有必要抽离出一些常用的配置。
整个Android项目的编译依赖于Gradle的编译,虽然前几天发布了Android 2.0 stable,拥有了Instant Run强大的功能,但是有“改一行布局代码Run一次”习惯的同学有必要知道如何加速Gradle的编译。
主要介绍一下:
如何配置Gradle
如何加速Gradle的编译
一些常用的项目构建知识
gradle.properties文件适合配置IDE的属性,当然也适合配置你在项目的关键/敏感参数,因为它将运行在Incubating parallel mode(
孵化并行模式,应该解释为运行时候嵌入在项目当中),也是属于默认的gitignore,这样你的敏感信息(key账号密码,appkey等)就不会被push到git了,你需要注意的是 属性中有中文的话,记得转成unicode来显示,不然可能引发一些莫名的错误
类似于这样,你可以把你的签名keystore的信息,服务端的endpoint,第三方服务的appkey,ide的配置信息放在这。
- KEY_ALIAS=yat3s
- KEYSTORE_PASSWORD=123456
- KEY_PASSWORD=123456
- umeng_appkey_product=adcdefghijk
- umeng_appkey_dev=adcdefghijk
- deepshare_appid=adcdefghijk
- bugly_appid_product=adcdefghijk
- bugly_appid_dev=adcdefghijk
- rong_appkey=adcdefghijk
- endpoint_product=http://api.yat3s.com
- endpoint_dev=http://api.yat3s.com:9000
- app_name=\u006f\u0070\u0065\u006e\u5f00\u8154`
那么配置好这些信息如何在Gradle和Java中使用呢?
其实Groovy语言和Java很接近也很好用,往下看↓
- buildTypes {
- release {
- minifyEnabled true
- shrinkResources true
- signingConfig signingConfigs.release
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- buildConfigField "String", "ENDPOINT", "\"${endpoint_product}\""
- resValue "string", "umeng_appkey", "${umeng_appkey_product}"
- resValue "string", "deepshare_appid", "${deepshare_appid}"
- resValue "string", "bugly_appid", "${bugly_appid_product}"
- resValue "string", "rong_appkey", "${rong_appkey}"
- resValue "string", "channel", "product"
- resValue "string", "op_app_name", "${app_name}"
- }
- debug {
- signingConfig signingConfigs.release
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- buildConfigField "String", "ENDPOINT", "\"${endpoint_product}\""
- resValue "string", "umeng_appkey", "${umeng_appkey_dev}"
- resValue "string", "deepshare_appid", "${deepshare_appid}"
- resValue "string", "bugly_appid", "${bugly_appid_dev}"
- resValue "string", "rong_appkey", "${rong_appkey}"
- resValue "string", "channel", "dev"
- resValue "string", "op_app_name", "dev_${app_name}"
- }
- }
记住几个点:
- 在你确保你minifyEnabled(混淆)没问题的时候debug模式尽量别开minifyEnabled和shrinkResources,这样会大大降低编译速度
- 如果真要开混淆,把生成mapping关掉
- 尽量把一些第三方key分成staging和product,这样容错性高,避免你推送给你的用户一个"Test"
- 定义buildConfigField时候注意双引号的问题 "\"${endpoint_product}\""
- 如果不方便管理签名可debug和release同一个签名。 如果需要同时安装debug和release包只需要修改applicationId即可
这里尽量新建一个Conifg.gradle文件来统一管理这些基本配置(在project下右键new file即可) ,
Config.gradle文件如下
- ext {
- android = [compileSdkVersion: 23,
- buildToolsVersion: "23.0.1",
- applicationId : "com.yat3s.d3v",
- minSdkVersion : 15,
- targetSdkVersion : 23,
- versionCode : 36,
- versionName : "1.3.1"]
- }
- dependencies = [
- design : "com.android.support:design:23.3.0",
- nineoldandroids : "com.nineoldandroids:library:2.4.0",
- retrofit : "com.squareup.retrofit:retrofit:2.0.0",
- rxandroid : "io.reactivex:rxandroid:1.0.0",
- okhttp-urlconnection: "com.squareup.okhttp:okhttp-urlconnection:2.0.0",
- okhttp : "com.squareup.okhttp:okhttp:2.0.0",
- butterknife : "com.jakewharton:butterknife:7.0.1"]
然后在项目的build.gradle文件下添加 apply from: "config.gradle"
- apply from: "config.gradle"
- buildscript {
- repositories {
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:2.0.0'
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
- }
- }
- allprojects {
- repositories {
- jcenter()
- }
- } ``
然后你使用起来就简单多了
- def config = rootProject.ext.android // 配置
- def dep = rootProject.ext.dependencies // 依赖
- useLibrary 'org.apache.http.legacy' // 如果你是api23的话,在用到apache的http库时候,记得加上这个,不然混淆时候因为urlConnection的升级导致异常
- compileSdkVersion config.compileSdkVersion
- buildToolsVersion config.buildToolsVersion
- defaultConfig {
- applicationId config.applicationId
- minSdkVersion config.minSdkVersion
- targetSdkVersion config.targetSdkVersion
- versionCode config.versionCode
- versionName config.versionName
- manifestPlaceholders = [UMENG_CHANNEL_VALUE: "open"]
- }
-
- dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile dep.design
- compile dep.retrofit
- compile dep.okhttp
- }
那么这样用的好处是什么呢?
- def keystore = file('keystore/yat3s.jks')
- signingConfigs {
- release {
- keyAlias KEY_ALIAS
- keyPassword KEY_PASSWORD
- storePassword KEYSTORE_PASSWORD
- storeFile keystore
- }
- }
- packagingOptions {
- exclude 'META-INF/LICENSE'
- exclude('META-INF/LICENSE.txt')
- exclude('META-INF/NOTICE.txt')
- exclude 'META-INF/NOTICE'
- exclude 'META-INF/DEPENDENCIES'
- // umeng推送的jar包含有的okio库跟okhttp的okio库冲突
- exclude 'META-INF/maven/com.squareup.okio/okio/pom.xml'
- exclude 'META-INF/maven/com.squareup.okio/okio/pom.properties'
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_7
- targetCompatibility JavaVersion.VERSION_1_7
- }
- lintOptions {
- disable "InvalidPackage"
- disable "MissingTranslation" // 禁用中英文string.xml的强制lint
- lintConfig file("lint.xml")
- }
- def getDate() {
- return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) // 注意时区
- }
-
- // 获取当前git的Revision
- def getRevision() {
- return ext.hash = 'git rev-parse --short HEAD'.execute().text.trim()
- }
- productFlavors {
- rc_open {}
- rc_360 {}
- rc_yingyongbao {}
- rc_baidu {}
- rc_91 {}
- rc_wandoujia {}
- rc_anzhuo {}
- rc_xiaomi {}
- rc_meizu {}
- rc_oppo {}
- rc_huawei {}
- rc_weibo {}
- rc_dev {}
- }
- productFlavors.all { flavor ->
- // 这里只是方便友盟统计每个渠道的数据
- flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
- }
-
- // 修改打包后APK的文件名
- applicationVariants.all { variant ->
- variant.outputs.each { output ->
- def oldFile = output.outputFile
- if (variant.buildType.name.equals('release')) {
- // 输出apk名称为yat3s_v1.0_2016-04-12_yingyongbao_a23f2e1.apk
- def releaseApkName = 'yat3s-v' + defaultConfig.versionName + '_' + getDate() + '_' + variant.productFlavors[0].name + "_" + getRevision() + '.apk'
- output.outputFile = new File(oldFile.parent, releaseApkName)
- }
- if (variant.buildType.name.equals('debug')) {
- // Do nothing
- }
- }
- }
我们都知道编译项目时候是依赖gradle的,gradle的构建速度决定了你的工作效率,上面零散的提到几点,下面总结一下:
- 第一个大招 升级Android studio 2.0 并且使用最新版的gradle 2.0 使用Instant Run
- 在你确保你的混淆没问题时候在debug模式下关闭所有混淆minifyEnabled false, shrinkResources false
- 尽可能的让你的所有module的依赖库版本一致。
- 在允许的情况下,在android studio的配置中,开启offline模式,在构建项目时候在命令后面加上--daemon --parallel --offline即可
- 在添加依赖的时候尽量明确版本号,省去gradle查找最新版的时间,不要compile 'com.facebook.fresco:fresco:latest' 或compile 'com.facebook.fresco:fresco:1.+',
- 开启守护线程并行编译,在gradle.properties中添加
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.jvmargs=-Xms256m -Xmx1024m- 在gradle中def方法的时候尽量在debug情况下减少耗时操作或者不操作,比如:
def getRevision() { if (!System.getenv('CI_BUILD')) { return 0 } return ext.hash = 'git rev-parse --short HEAD'.execute().text.trim() }
如果那里写的不对或者有更好的方式,欢迎指出批评,感恩。欢迎关注~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。