Gradle在Android中的自定义用法

参考链接:

《Android Developer》
《Android Plugin DSL》

使用共享库

在Android中除了标准的SDK还存在两种库:

一种是add-ons库(位于sdk的add-ons目录下,大部分是第三方厂商或者公司开发的)
一种是optional库(位于platforms/android-xx/optional目录下,一般是为了兼容旧版本的API)

第一类库Android Gradle会自动解析,帮我们添加到classpath中。
第二类库需要我们自己手动添加到classpath中。

1
2
3
android {
useLibrary 'org.apache.http.legacy'
}

最好在AndroidManifest文件里面配置一下uses-library标签,类似于google Maps如下:

1
2
3
<uses-library
android:name="com.google.android.maps"
android:required="true"/>

批量生成apk文件名

Android Gradle为我们提供了三个属性:applicationVariants、libraryVariants、testVariants.
这三个属性都返回DomainObjects对象集合,里面的元素分别是ApplicationVariant、LibraryVariants和TestVariants.修改它们会自动触发创建所有任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

android{

//....

applicationVariants.all { variant ->
variant.outputs.each { output ->
if (output.outputFile != null && output.outputFile.name.endsWith('.apk')
&& 'release'.equals(variant.buildType.name)){
def flavorName = variant.flavorName.startWith("_") ? variant.flavorName.
substring(1) : variant.flavorName
def apkFile = new File(output.outputFile.getParent(),
"Project_${flavorName}_v${variant.versionName}_${buildTime()}.apk")
}
}
}

def buildTime(){
def date = new Date()
def formattedDate = date.format("yyMMdd")
return formattedDate
}
}

applicationVariants中的variant都是ApplicationVariant,通过查看源码,可以看到它有一个outputs作为它的输出。

动态生成版本信息

version.gradle

1
2
3
4
ext{
appVersionCode=1
appVersionName="1.0.0"
}

build.gradle

1
2
3
4
5
6
7
8
9
apply from 'version.gradle'

android{

defaultConfig{
versionCode appVersionCode
versionName appVersionName
}
}

隐藏签名文件信息

对于apk的签名文件以及密码,我们存放到版本库和服务器都不是很好,所以下面将这些信息配置到本地环境变量再获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
android{
compileSdkVersion 27
buildToolsVersion '28.0.3'

signingConfigs {

def appStoreFile = System.getenv("STORE_FILE")
def appStorePassword = System.getenv("STORE_PASSWORD")
def appKeyAlias = System.getenv("KEY_ALIAS")
def appKeyPassword = System.getenv("KEY_PASSWORD")

release {
storeFile file(appStoreFile)
storePassword appStorePassword
keyAlias appKeyAlias
keyPassword appKeyPassword
}
}
}
}

动态配置AndroidManifest文件

1
<meta-data android:name="CHANNEL_NAME" android:value="${CHANNEL_VALUE}" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
android{

productFlavors{

google{

}

baidu{

}
}

productFlavors.all{ flavor ->
manifestPlaceholders.put("CHANNEL_NAME", name)
}
}

Android Gradle提供的manifestPlaceholders占位符方式,可以替换Manifest文件中任意${valu}格式的占位符。

自定义BuildConfig

BuildConfig类是Android工程自动生成的,不允许修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.parkingwang.business;

public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.parkingwang.business";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "Appium";
public static final int VERSION_CODE = 54001;
public static final String VERSION_NAME = "5.4.1";
// Fields from product flavor: Appium
public static final boolean DISABLE_KEYBOARD = true;
public static final boolean USING_TEST_API = true;
// Fields from default config.
}

可以看到这里面有一些配置信息,是否debug、appid、版本号、版本名称等,如果有所变化这些配置信息都会自动修改的。

Android Gradle提供了buildConfigField(String type, String name, String value)让我们自己添加到BuildConfig中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Adds a new field to the generated BuildConfig class.
*
* <p>The field is generated as: {@code <type> <name> = <value>;}
*
* <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){ //... }

这样我们就可以使用这个特点结合productFlavors来配置不同渠道下的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
android{

productFlavors{

google{
buildConfigField 'String', 'WEB_URL', 'http://www.google.com'
}

baidu{
buildConfigField 'String', 'WEB_URL', 'http://www.baidu.com'
}
}
}

利用这个特点我们就可以不同的渠道做一些特殊的处理。

动态自定义资源文件

res/values类型的资源文件可以在Android Gradle中定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
android{
compileSdkVersion 27
buildToolsVersion '28.0.3'

productFlavors{

google{
resValue 'string', 'channel_tips', 'google渠道'
}
baidu{
resValue 'string', 'channel_tips', 'baidu渠道'
}
}
}

这样我们在工程中使用channel_tips字符串的时候就会相应的使用对应渠道的字符串内容。

除了string资源之外,还可以使用 id、bool、dimen、integer、color等资源。

Java编译选项

有的时候我们需要配置JDK的版本来使用一些新的特性,Android Gradle给我们提供了一种方便的配置方式。

1
2
3
4
5
6
7
8
9
10
android{
compileSdkVersion 27
buildToolsVersion '28.0.3'

compileOptions{
encoding = 'utf-8'
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}

adb操作配置

adbOptions有两个属性:installOptions和timeOutInMs

1
2
3
4
5
6
7
8
9
android{
compileSdkVersion 27
buildToolsVersion '28.0.3'

adbOptions{
timeOutInMs = 5 * 1000 //秒
installOptions = '-r', '-s'
}
}

timeOutInMs是设置adb命令的超时时间,单位为毫秒。
installOptions是adb install 的可选参数。

参数含义
-l锁定该应用程序
-r替换已存在的应用程序,强制安装
-t允许测试包
-s把应用程序安装到SD卡
-d允许进行降级安装
-g为该应用程序授予所有运行时权限

DEX选项配置

dx命令是一个脚本,调用的是dx.jar,默认情况下给dx分配1024M内存。Android Gradle提供了dexOptions{ }对dx操作进行一些配置。

1
2
3
4
5
6
7
8
android{
compileSdkVersion 27
buildToolsVersion '28.0.3'

dexOptions{
incremental true
}
}

incremental 属性是dx的增量模式,速度更快一些,有很多限制可能会不工作,所以慎用。

javaMaxHeapSize 属性解决dx时的内存不足问题,可以配置一个内存大小。

1
2
3
dexOptions{
javaMaxHeapSize '4g'
}

jumboMode 属性用来配置是否开启jumbo模式,也就是65535问题(Android 5.0及以上可用)。

1
2
3
dexOptions{
jumboMode true
}

preDexLibraries 属性配置是否开启执行dex Libraries库工程。

threadCount属性配置dx运行时候的线程数量。

评论

Ajax Android AndroidStudio Animation Anroid Studio AppBarLayout Banner Buffer Bulma ByteBuffer C++ C11 C89 C99 CDN CMYK COM1 COM2 CSS Camera Raw, 直方图 Chrome ContentProvider CoordinatorLayout C语言 DML DOM Dagger Dagger2 Darktable Demo Document DownloadManage Element Error Exception Extensions File FileProvider Fresco GCC Git GitHub GitLab Gradle Groovy HTML5 Handler HandlerThread Hexo Hybrid I/O IDEA IO ImageMagick IntelliJ Intellij Interpolator JCenter JNI JS Java JavaScript JsBridge Kotlin Lab Lambda Lifecycle Lint Linux Looper MQTT MVC MVP Maven MessageQueue Modbus Momentum MySQL NDK NIO NexT Next Nodejs ObjectAnimator Oracle VM Permission PhotoShop Physics Python RGB RS-232 RTU Remote-SSH Retrofit Runnable RxAndroid RxJava SE0 SSH Spring SpringBoot Statubar Task Theme Thread Tkinter UI UIKit UML VM virtualBox VS Code ValueAnimator ViewPropertyAnimator Web Web前端 Workbench api apk bookmark by关键字 compileOnly css c语言 databases demo hexo hotfix html iOS icarus implementation init jQuery javascript launchModel logo merge mvp offset photos pug query rxjava2 scss servlet shell svg tkinter tomcat transition unicode utf-8 vector virtual box vscode 七牛 下载 中介者模式 串口 临潼石榴 主题 书签 事件 享元模式 仓库 代理模式 位运算 依赖注入 修改,tables 光和色 内存 内核 内部分享 函数 函数式编程 分支 分析 创建 删除 动画 单例模式 压缩图片 发布 可空性 合并 同向性 后期 启动模式 命令 命令模式 响应式 响应式编程 图层 图床 图片压缩 图片处理 图片轮播 地球 域名 基础 增加 备忘录模式 外观模式 多线程 大爆炸 天气APP 太白山 头文件 奇点 字符串 字符集 存储引擎 宇宙 宏定义 实践 属性 属性动画 岐山擀面皮 岐山肉臊子 岐山香醋 工具 工厂模式 年终总结 开发技巧 异常 弱引用 恒星 打包 技巧 指针 插件 摄影 操作系统 攻略 故事 数据库 数据类型 数组 文件 新功能 旅行 旋转木马 时序图 时空 时间简史 曲线 杂谈 权限 枚举 架构 查询 标准库 标签选择器 样式 核心 框架 案例 桥接模式 检测工具 模块化 模板引擎 模板方法模式 油泼辣子 泛型 洛川苹果 浅色状态栏 源码 瀑布流 热修复 版本 版本控制 状态栏 状态模式 生活 留言板 相册 相对论 眉县猕猴桃 知识点 码云 磁盘 科学 笔记 策略模式 类图 系统,发行版, GNU 索引 组件 组合模式 结构 结构体 编码 网易云信 网格布局 网站广播 网站通知 网络 美化 联合 膨胀的宇宙 自定义 自定义View 自定义插件 蒙版 虚拟 虚拟机 补码 补齐 表单 表达式 装饰模式 西安 观察者模式 规范 视图 视频 解耦器模式 设计 设计原则 设计模式 访问者模式 语法 责任链模式 贪吃蛇 转换 软件工程 软引用 运算符 迭代子模式 适配器模式 选择器 通信 通道 配置 链表 锐化 错误 键盘 闭包 降噪 陕西地方特产 面向对象 项目优化 项目构建 黑洞
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×