转载请标注原文:http://blog.csdn.net/hawkoyates/article/details/51128688

Why Gradle

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的编译
  • 一些常用的项目构建知识

How Gradle

gradle.properties文件适合配置IDE的属性,当然也适合配置你在项目的关键/敏感参数,因为它将运行在Incubating parallel mode(
孵化并行模式,应该解释为运行时候嵌入在项目当中),也是属于默认的gitignore,这样你的敏感信息(key账号密码,appkey等)就不会被push到git了,你需要注意的是* 属性中有中文的话,记得转成unicode来显示,不然可能引发一些莫名的错误 *

类似于这样,你可以把你的签名keystore的信息,服务端的endpoint,第三方服务的appkey,ide的配置信息放在这。

KEY_ALIAS=yat3sKEYSTORE_PASSWORD=123456KEY_PASSWORD=123456umeng_appkey_product=adcdefghijk   umeng_appkey_dev=adcdefghijkdeepshare_appid=adcdefghijkbugly_appid_product=adcdefghijk  bugly_appid_dev=adcdefghijk  rong_appkey=adcdefghijk   endpoint_product=http://api.yat3s.comendpoint_dev=http://api.yat3s.com:9000app_name=\u006f\u0070\u0065\u006e\u5f00\u8154

* 那么配置好这些信息如何在Gradle和Java中使用呢?*
其实Groovy语言和Java很接近也很好用,往下看↓

buildTypes

   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}"     }   }
  • 引用gradle.properties 只需要加 ${key}
  • 定义在 buildConfigField “String”, “ENDPOINT”,”\”${endpoint_product}\”“,在Java享用时候只需要读取BuildConfig.ENDPOINT即可
  • 定义在 resValue “string”, “umeng_appkey”, “${umeng_appkey_product}” , 在xml中享用只需要R.string.umeng_appkey即可

记住几个点:

  • 在你确保你minifyEnabled(混淆)没问题的时候debug模式尽量别开minifyEnabled
    和shrinkResources,这样会大大降低编译速度
  • 如果真要开混淆,把生成mapping关掉
  • 尽量把一些第三方key分成staging和product,这样容错性高,避免你推送给你的用户一个”Test”
  • 定义buildConfigField时候注意双引号的问题 “\”${endpoint_product}\”“
  • 如果不方便管理签名可debug和release同一个签名。* 如果需要同时安装debug和release包只需要修改applicationId即可 *

defaultConfig

这里尽量新建一个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.compileSdkVersionbuildToolsVersion config.buildToolsVersiondefaultConfig {  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}

那么这样用的好处是什么呢?
- 如果你有多个Module都需要依赖design包的话,design包一升级导致了多个module需要改版本,你就可能同时引入了多个依赖导致apk增大
- 统一管理versionCode和versionName
- 看起来是不是更简洁

![](http://ww3.sinaimg.cn/large/0060lm7Tgw1f2t8n81eusj30h40kemzj.jpg
)

signingConfigs

def keystore = file('keystore/yat3s.jks')signingConfigs {    release {        keyAlias KEY_ALIAS        keyPassword KEY_PASSWORD        storePassword KEYSTORE_PASSWORD        storeFile keystore    }}    

- 在非资源定义下引用gradle.properties可直接输入properties的key
- 如果你要公开你的源码记得把你的keystore ignore掉,私有库无视

packagingOptions

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'}
  • 主要处理第三方库在导入时候的一些声明文件冲突,Option this

compileOptions {

compileOptions {  sourceCompatibility JavaVersion.VERSION_1_7  targetCompatibility JavaVersion.VERSION_1_7}
  • 个人觉得如果你不用lambda表达式的话,可以用java1.7,因为1.8还不是完美的支持Android

lintOptions

 lintOptions {    disable "InvalidPackage"    disable "MissingTranslation" // 禁用中英文string.xml的强制lint    lintConfig file("lint.xml")}

- lint可以帮你查找到很多warning和error,帮你优化很多问题,如果不了解可以到官网http://developer.android.com/intl/zh-cn/tools/help/lint.html look一下

打包管理

def getDate() {    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) // 注意时区}     // 获取当前git的Revisiondef 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的productFlavors
  • git的Revision 方便你管理你的release和tag
  • 打包的时候可以用Jenkins来自动Build你的包

Speed Gradle

我们都知道编译项目时候是依赖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()
    }

写在最后

如果那里写的不对或者有更好的方式,欢迎指出批评,感恩。

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. 一款常用的 Squid 日志分析工具
  3. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  4. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  5. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  6. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
  7. Android(安卓)UI 之 ListView
  8. Android(安卓)requires compiler compliance level 5.0 or 6.0.
  9. LinearLayout中添加分割线

随机推荐

  1. Android调用系统自带软件
  2. Android中关于空指针异常的解决办法
  3. Android之提示java.lang.RuntimeExceptio
  4. Java的 ProcessBuilder & Process| 在and
  5. 【Android】GestureDetector 类的手势操
  6. Android处理时间各种方法汇总
  7. Sense4+ Android(安卓)4.1.1去除拨号连接
  8. Android(安卓)Studio Check Updates Conn
  9. Hbuild项目Android本地打包
  10. Android对px和dip进行尺寸转换的方法