转载请注明出处:http://blog.csdn.net/crazy1235/article/details/50465885

Google I/O 2013大会上发布了AS,如今已经发展到2.0-beta版本。相信已经大部分人做Android开发的都已经由Eclipse IDE转为AS IDE。

随着AS版本的更迭,也带来不少为为开发者提供便利的工具。比如这篇blog所描述的:http://blog.csdn.net/crazy1235/article/details/49747141

本人从AS1.2版本开始使用,如今也用了大半年了。现将使用过程中的一些经验分享给大家。

  • gradle的基本配置
  • gradle的签名配置
  • 配置buildTypes
  • 配置productFlavor
  • manifest占位符
  • 添加自定义字段
  • 自定义导出APK的名称
  • Demo下载

gradle的基本配置

apply plugin: 'com.android.application'android {compileSdkVersion 23buildToolsVersion "23.0.2"defaultConfig {applicationId "com.jacksen.multichannel"minSdkVersion 14targetSdkVersion 23versionCode 1versionName "1.0"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])testCompile 'junit:junit:4.12'compile 'com.android.support:appcompat-v7:23.1.1'compile 'com.android.support:design:23.1.1'
}

上面的就是一个项目gradle的基本配置。

apply plugin: 'com.android.application'

表示该module是一个app module,应用了com.android.application插件,也就是主程序。如果是一个第三方library,则应该是app plugin: ‘com.android.library’

buildTypes { } 表示构建类型。包括release和debug两种。可以在这里面配置启用混淆、zipAlign、签名信息等。

dependencies { } 里面是项目的依赖信息,包括jar包和第三方库等信息。

ApplicationId与PackageName的区别:

此前使用eclipse进行开发的时候,应用程序的包名是由manifest文件的package属性决定的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.xxx.xxxx"android:versionCode="1"android:versionName="1.0" >

然而在使用gradle构建的时候却多了一个applicationId。通常gradle中的applicationId和Manifest中的package是一样的。其实可以使二者一致。

官方解释说是:applicationId是你的应用在商店的唯一标识。而package是引用资源的路径名,也就是R文件的包名。

上面我们说到二者可以不一致,我们可以通过对不同的Flavor设置不同的applicationId,从而可以导出不同“包名”的apk,而不需要修改其他的代码。后面会仔细说明。


gradle的签名配置

关于签名的概念不懂得,可以参考这篇blog:Android从零单排之签名打包

我们通常运行项目都是使用debug的签名。不过有些使用到第三方sdk的时候,需要用到正式版的签名,通过打包正式签名的方式又不好调试。不过我们可以在gradle里面配置正式版的签名。

android {signingConfigs {config_release {keyAlias 'releaseKey'keyPassword '123456'storePassword '123456'storeFile file('key/releaseKey.jks')}config_debug {keyAlias 'debugKey'keyPassword '123456'storePassword '123456'storeFile file('key/debugKey.jks')}}......//省略其他配置
}

这里配置了两个签名。jsk都放在app下面的key文件夹中。所以使用的是相对路径。

之前有人问我是怎么知道keyAlias 、keyPassword这些语法的。其实在项目的【Project Structure】中都可以找到。


配置buildTypes

一般在buildTypes{ }里面配置两个(release和debug):

buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'shrinkResources true //移除无效的resource文件,必须允许ProGuard才能生效zipAlignEnabled truebuildConfigField "boolean", "APP_TYPE", "true"manifestPlaceholders = [APP_NAME: "@string/app_name_release"]signingConfig signingConfigs.config}debug {buildConfigField "boolean", "APP_TYPE", "false"
//            manifestPlaceholders = [APP_NAME: "@string/app_name_debug"]applicationIdSuffix 'debug'}}

这里可配置的信息很多,比如:是否可以是debug模式、签名配置、混淆文件等。


配置productFlavor

多渠道打包,关键就在于定义多个productFlavor。

在一个flavor里面可配置的信息很多。

productFlavors {flavor_release {buildConfigField "boolean", "APP_TYPE", "false"applicationId 'com.jacksen.multichannel.release'signingConfig signingConfigs.config_releaseminSdkVersion 9targetSdkVersion 15versionCode 2versionName '2.0.1'}flavor_debug {minSdkVersion 10applicationId 'com.jacksen.multichannel.debug'signingConfig signingConfigs.config_debugversionCode 5versionName '5.0'}}

最主要的是可以在这里配置applicationId,就是我们上面一开始说的打包多个不同“包名”的apk。

这样有一个应用场景就是,我们一般通过debug版本进行测试之后,在进行release版本的测试。不过同一个applicationId的apk在一个测试机上只能存在一个。现在我们通过配置多个flavor对应多个applicationId,就可以在测试机上运行测试版和正式版两个apk了


productFlavors{ } 与 buildTypes{ }里面的配置是多对多的关系。
比如:

buildTypes {release {...}debug {...}
}
productFlavors {flavor_1 {...}flavor_2 {...}
}

此时的配置可以打包出四个apk,分别是:

我们在使用as的打包工具时,可以选择打包某一个Build type的某一个或多个Flavors:

如果在gradle里面配置了签名信息,那么在【Generate Signed APK】的第一步填写的签名信息是以在gradle里面配置并引用的为准。

我们还可以借助gradlew命令来打包:
比如打包flavor_1对应的release和debug版本:

打包flavor_2对应的release版本:

实际上,我们不用再记住这些命令。AS里面的gradle插件就可以实现。
在AS的右侧会有【Gradle】tab页面。打开之后,先刷新一下。会看到如下图示:

通过双击右边的命令打包不同的版本。

除了build下面的命令,还有其他的命令,大家都可以尝试一下,根据名字应该就能知道什么意思,这里不多介绍了。


manifest占位符

在打包多个版本的时候,会遇到修改应用名称等需求。不同的flavor有要求不通的名称。此时可以在Manifest文件中使用占位符,然后在build.gradle中替换占位符就行了。

首先定义占位符:

applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="${APP_NAME}"android:supportsRtl="true"android:theme="@style/AppTheme"><activityandroid:name=".LoginActivity"android:label="${APP_NAME}"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>

在build.gradle中替换:

buildTypes {release {manifestPlaceholders = [APP_NAME: "@string/app_name1"]}debug {manifestPlaceholders = [APP_NAME: "@string/app_name1"]}}
 productFlavors {flavor_1 {manifestPlaceholders = [APP_NAME: "@string/app_name1"]}flavor_2 {manifestPlaceholders = [APP_NAME: "@string/app_name2"]}}

如果在productFlavors和buildTypes里面都进行了替换,那么是以productFlavors里面的为准

如果不区分productFlavors和buildTypes的话,也可以在defaultConfig里进行替换:

defaultConfig {manifestPlaceholders = [APP_NAME: "@string/app_name_release"]}

其实defaultConfig也是productFlavors的一个子集。


添加自定义字段

Gradle在generateSources阶段为每一个flavor生成两个BuildConfig.java文件(对应在release和debug文件夹下)。

BuildConfig类默认会提供一些常量字段。

public final class BuildConfig {public static final boolean DEBUG = Boolean.parseBoolean("true");public static final String APPLICATION_ID = "com.jacksen.multichannel";public static final String BUILD_TYPE = "debug";public static final String FLAVOR = "";public static final int VERSION_CODE = 1;public static final String VERSION_NAME = "1.0";
}

虽然通过上面的操作,我们可以同时打包出一个debug版本和一个release版本。但是我们还需要运行的时候有不同的表现。比如,release版本不显示一些控件。

令人惊奇的是,我们可以通过buildConfigField在gradle里面自定义一些字段。

buildConfigField "String", "APP_TYPE", "debug"

我们可以查看buildConfigField的源码:

/*** Adds a new field to the generated BuildConfig class.** <p>The field is generated as: <code>&lt;type&gt; &lt;name&gt; = &lt;value&gt;;</code>** <p>This means each of these must have valid Java content. If the type is a String, then the* value should include quotes.** @param type the type of the field* @param name the name of the field* @param value the value of the field*/public void buildConfigField(@NonNull String type,@NonNull String name,@NonNull String value) {ClassField alreadyPresent = getBuildConfigFields().get(name);if (alreadyPresent != null) {logger.info("BuildType(${getName()}): buildConfigField '$name' value is being replaced: ${alreadyPresent.value} -> $value");}addBuildConfigField(AndroidBuilder.createClassField(type, name, value));}

注释写的很详细。该方法就是添加一个field到BuildConfig类中。三个参数都是不可为空的

添加完毕之后,就可以在代码中使用了:

textView.setText("BuildConfig.APP_TYPE : " + BuildConfig.APP_TYPE);

自定义导出APK的名称

我直接上代码吧。

/*applicationVariants.all {variant ->variant.outputs.each {output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('.apk')) {
//                        def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")def apkType = ""if (variant.flavorName.equals("releaseFlavor")){apkType = "release"}else if(variant.flavorName.equals("debugFlavor")){apkType = "debug"}def fileName = new File(output.outputFile.getParent(), "app-" + apkType + "-${variant.versionName}.apk")
//                        output.outputFile = new File(outputFile.parent, fileName)output.outputFile = fileName}}}*/applicationVariants.all {variant ->variant.outputs.each {output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('.apk')) {def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionCode}-${defaultConfig.versionName}.apk")output.outputFile = new File(outputFile.parent, fileName)}}}

这里有两种方式,大家运行一下测试一下就明白了。

以上就是我对gradle的一些认识~~~


Demo下载

https://github.com/crazy1235/MultiChannel

欢迎star~~


参考:
http://tech.meituan.com/mt-apk-adaptation.html
http://www.jayfeng.com/2015/11/07/Android%E6%89%93%E5%8C%85%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B/
http://www.jcodecraeer.com/a/anzhuokaifa/Android_Studio/2015/0810/3281.html


此篇blog到此结束~
感谢大家支持!如有错误,请指出~
谢谢~

Gradle的神奇之处相关推荐

  1. 揭秘:蓝光光碟“造”太阳能电池的神奇之处

    OFweek光学网讯:蓝光光碟以提供高存储容量和高品质影音著称.不过最近,美国西北大学材料科学与工程系黄嘉兴副教授的研究团队发现,只用蓝光光碟看片实在太屈才了--他们将成龙的<警察故事Ⅲ:超级警 ...

  2. 【转】RNN的神奇之处(The Unreasonable Effectiveness of Recurrent Neural Networks)

    转自:https://blog.csdn.net/menc15/article/details/78775010 本文译自http://karpathy.github.io/2015/05/21/rn ...

  3. RNN的神奇之处(The Unreasonable Effectiveness of Recurrent Neural Networks)

    本文译自http://karpathy.github.io/2015/05/21/rnn-effectiveness/.结合个人背景知识,忠于原文翻译,如有不明欢迎讨论. 以下正文. RNN有很多神奇 ...

  4. 究竟Python语言有什么神奇之处,让它如此火爆?

    从你开始学习编程的那一刻起,就注定了以后所要走的路-从编程学习者开始,依次经历实习生.程序员.软件工程师.架构师.CTO等职位的磨砺:当你站在职位顶峰的位置蓦然回首时,会发现自己的成功并不是偶然,在程 ...

  5. “想象之中”,【玉石雕刻刀】的神奇之处

    "想象之中"[玉石雕刻刀]的神奇之处 玉石雕刻刀雕刻深度的问题  浮动刀头顾名思义是在雕刻平面上,可在一定的范围内上上下浮动.主轴在Z轴方向上是可上下滑动的,当使用浮动刀头时注重于 ...

  6. 单管发报机的神奇之处-身兼两职

    ➤01 简易无线发报机 1.发报机演示 在头条上有一个视频,介绍了一款 简易无线发报机 ,给了一款仅仅使用一个高频硅三极管( 9018 )构成的调幅无线发报机.虽然是一个高频电路,为了说明电路的构造原 ...

  7. 单元测试框架怎么搭?快来看看新版Junit5的这些神奇之处吧!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 为什么使用JUnit5 JUnit4被广泛使用,但是许多场 ...

  8. 竟然在GitHub标星27k+阿里大牛肝出的443页TCP/IP协议趣谈笔记,有何神奇之处?

    前言: 十个人程序员里面,有十个都会说自己学过网络协议,九个人都会说自己懂网络协议.但是面试的时候,问几个问题,能回答的可能只有两三个.不信?来,我问你几道. 1.TCP 协议跟 UDP 协议有什么区 ...

  9. 微型计算机上面的Tab键,电脑键盘上Tab 键的神奇之处!(用途详解)

    下面通过实例来详细解释下: 假设"D:\cfan"路径下,有文件夹: a. ab ,有文件: abc.txt , ac.txt .依次点击"开始→运行"输入&q ...

  10. 三分钟创建一个新应用,ivx的神奇之处【PPT式程序开发】

    像做PPT一样的可视化编程语言你想拥有吗,可以自己尝试一下.像PPT一样的编程语言 文章目录

最新文章

  1. main方法_你知道为什么Java的main方法必须是public static void?
  2. 需要监控JanusGraph的一些指标
  3. 【netty】netty HashedWheelTimer 延时队列
  4. 【工程项目经验】多个静态库打包成一个静态库
  5. C语言读取图像像素坐标,OpenCL中读取image时的坐标
  6. 从零开始,我用了两年半逆袭秋招!
  7. (day 19 - 动态规划)剑指 Offer 42. 连续子数组的最大和
  8. 制作OpenStack xpsp3镜像
  9. python读书心得体会范文_读书心得体会范文6篇
  10. 文本相似度计算(中英文)详解实战
  11. [编译原理随记]正则表达式转为NFA状态图(Thompsion构造法)
  12. pc模拟器运行多个Android,低配电脑如何强制开50个安卓模拟器挂机
  13. 浅谈public static void main(String[] args)
  14. 西电工作笔记(部分)【10000字】【原创】
  15. vue实现 导出为word模板
  16. 2023年Java面试题大全(最新版版)面试题附答案详解,看完BTA可进
  17. [激光原理与应用-41]:《光电检测技术-8》- 白光干涉仪
  18. 实现一个 柯里化函数
  19. 只需+1s,GitHub代码一键转成VS Code
  20. 小程序实现图片放大预览功能

热门文章

  1. ae合成设置快捷键_AE脚本使用快捷键控制关键帧操作 Keyboard v1.2.1 + 使用教程【资源分享1081】...
  2. maven [INFO] No proxies configured [INFO] No proxy was configured, downloading directly
  3. 什么是Web前端工程师?为什么Web前端工资如此之高呢?
  4. 虚拟机安装CentOS6.5分配内存一般20G,之后如何扩展内存,扩充磁盘!
  5. 如何实现网易公开课的倍速播放?
  6. 数据智能,慧眼识“真”——个推大数据风控产品亮相
  7. 文本信息过滤中的变体词识别(一)
  8. 【non-coding RNA】 非编码RNA有哪些?
  9. 怎么把系统桌面设置到D盘
  10. 专转本-矩阵的初等变换与线性方程组