当前位置: 首页 > news >正文

Android中Gradle常用配置

前言
本文记录了一些常用的gradle配置,基本上都是平时开发中可能会使用到的,如果有新内容会不定时更新,附官网

1.依赖库版本写法
不推荐写法:

dependencies {compile 'com.example.code.abc:def:2.+' // 不推荐的写法
}

这样写虽然可能保证每次都保持库是最新的,但同时会有以下更严重的问题:
1)多人开发时,每个人可能会得到不同的最新版本,带来潜在的隐患;
2)库更新后,可能会由于库的内部代码的修改而引起不易发现的BUG;
3)每次build时会联网检查,增加build时间。

推荐写法(固定版本):

dependencies {compile 'com.example.code.abc:def:2.0.1' // 固定版本,有需要时再进行修改
}

2.全局设置编码
在最顶层的build.gradle中添加:

allprojects {repositories {jcenter()}tasks.withType(JavaCompile){options.encoding = "UTF-8"}
}

3.设置Java编译版本
在module中的build.gradle中:

android {compileOptions {sourceCompatibility JavaVersion.VERSION_1_7targetCompatibility JavaVersion.VERSION_1_7}
}

全局配置则在最顶层的build.gradle中:

allprojects {repositories {jcenter()}tasks.withType(JavaCompile) {sourceCompatibility = JavaVersion.VERSION_1_7targetCompatibility = JavaVersion.VERSION_1_7}
}

4.Release版本的密码配置
密码、签名等敏感信息可以统一进行存放,不进行硬编码。写在gradle.properies中,可以随意的定义key-value形式,此文件是gradle自动引入的。
例:gradle.properies文件如下

STORE_FILE_PATH ../test_key.jks
KEYSTORE_PASSWORD 123456
KEY_ALIAS abc
KEY_PASSWORD 654321
PACKAGE_NAME_SUFFIX .test
TENCENT_AUTHID aaa0123
module的build.gradle文件:signingConfigs {release {try {storeFile file(STORE_FILE_PATH)storePassword STORE_PASSWORDkeyAlias KEY_ALIASkeyPassword KEY_PASSWORD}catch (ex) {throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.")}}
}

5.设置第三方maven仓库
在顶层的build.gradle中:

allprojects {repositories {maven {url 'http://repo.xxxx.net/nexus/'name 'maven name'credentials {username = 'username'password = 'password'}}}
}

其中name和credentials是可选项,视具体情况而定。如使用阿里云仓库如下:

allprojects {repositories {maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }}
}

6.自动删除unaligned apk
每次打包后都会有一个unaligned的apk文件生成,这个文件对于开发来说无意义,可以配置一个task来删除它。
写在module的build.gradle中:

dependencies {compile fileTree(include: ['*.jar'], dir: 'libs')
}
android.applicationVariants.all { variant ->variant.outputs.each { output ->// 删除unaligned apkif (output.zipAlign != null) {output.zipAlign.doLast {output.zipAlign.inputFile.delete()}}}
}

7.lint选项开关
lint默认会做严格检查,遇到包错误会终止构建过程。可以用如下开关关掉这个选项,非特殊情况不最好不配置。
写在module的build.gradle中:

android {lintOptions {disable 'InvalidPackage'checkReleaseBuilds falseabortOnError false}
}

8.依赖项目中的module和jar
工程可以依赖自身的module和jar文件,如下:

dependencies {compile project(':myExamplelibraryModule')compile files('libs/sdk-1.1.jar')
}

9.根据buildType设置包名
写在module的build.gradle中:

android {defaultConfig {applicationId "example" // 这里设置了example作为默认包名}buildTypes {release {applicationIdSuffix '.abc.gradle' // 设置release时的包名为example.abc.gradle}debug{applicationIdSuffix '.abc.debug' // 设置debug时的包名为example.abc.debug}}

10.替换AndroidManifest中的占位符
在manifest中可以有类似{appName}这样的占位符,在module的build.gradle中可以将其进行赋值。

android{defaultConfig{manifestPlaceholders = [appName:"@string/app_name"]}
}

11.定义全局变量
先在顶层的build.gradle定义全局变量:

ext {minSdkVersion = 19targetSdkVersion = 24
}

然后在各module的build.gradle中可以通过rootProject.ext来引用:

android {defaultConfig {minSdkVersion rootProject.ext.minSdkVersiontargetSdkVersion rootProject.ext.targetSdkVersion}
}

如果是在当前文件中定义的,就不用添加rootProject.ext。

12.定义局部变量
有时候一个库会被引用多次,或者一个库有多个依赖,但这些依赖的版本都是统一的。通过ext来定义一些变量,这样在用到的时候就可以统一使用了:

ext {rxandroidVersion = '2.0.1'rxjavaVersion = "2.1.0"
}dependencies {...compile "io.reactivex.rxjava2:rxandroid:$rxandroidVersion"compile "io.reactivex.rxjava2:rxjava:$rxjavaVersion"
}

13.动态设置额外信息
假如想把当前的编译时间、编译的机器、最新的commit版本添加到apk中,动态设置如下:

android {defaultConfig {resValue "string", "build_time", buildTime()resValue "string", "build_host", hostName()resValue "string", "build_revision", revision()}
}
def buildTime() {return new Date().format("yyyy-MM-dd HH:mm:ss")
}
def hostName() {return System.getProperty("user.name") + "@" + InetAddress.localHost.hostName
}
def revision() {def code = new ByteArrayOutputStream()exec {commandLine 'git', 'rev-parse', '--short', 'HEAD'standardOutput = code}return code.toString()
}

上述代码实现了动态添加了3个字符串资源: build_time、build_host、build_revision, 在其他地方可像引用strings.xml中的字符串一样使用:

getString(R.string.build_time)  // 输出2017-06-12 15:05:05
getString(R.string.build_host)  // 输出zyr@example,这是我的电脑的用户名和PC名
getString(R.string.build_revision) // 输出5ff4x89, 这是最后一次commit的sha值

上面讲到的是植入资源文件,同样可以在BuildConfig.class中增加自己的静态变量:

defaultConfig {applicationId "zyr.gradle.demo"minSdkVersion 19targetSdkVersion 24buildConfigField("boolean", "IS_TEST", "true") // 定义一个bool变量resValue "string", "build_time", "2017.06.12" // 上面讲到的植入资源文件
}

在sync后BuildConfig中就有定义的这个变量了:

public final class BuildConfig {public static final boolean DEBUG = Boolean.parseBoolean("true");public static final String APPLICATION_ID = "zyr.gradle.test";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.0";// Fields from default config.public static final boolean IS_TEST = true;
}

如果有带引号的string,需要转义:

 buildConfigField "String", "URL_ENDPOINT", "\"http://your.development.example.com/\""

14.使用init.with继承配置
如果想新增一个buildType,又想新的buildType继承之前配置好的参数,使用init.with()。

buildTypes {release {zipAlignEnabled trueminifyEnabled trueshrinkResources true // 是否去除无效的资源文件proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'signingConfig signingConfigs.release}abcd.initWith(buildTypes.release) // 继承release的配置abcd {...}}

15.exlude关键字
遇到库冲突的问题时,将冲突的库通过exclude来剔除:

剔除整个组织的库:
compile ('com.facebook.fresco:animated-webp:0.13.0') {exclude group: 'com.android.support' // 仅仅写组织名称
}
剔除某个库:
compile('com.android.support:appcompat-v7:23.2.0') {exclude group: 'com.android.support', module: 'support-annotations' // 写全称exclude group: 'com.android.support', module: 'support-compat'exclude group: 'com.android.support', module: 'support-v4'exclude group: 'com.android.support', module: 'support-vector-drawable'
}

16.聚合依赖多个库
有时候一些库是一并依赖的,剔除也是要一并剔除的,此时进行统一引入:

compile(['io.reactivex.rxjava2:rxandroid:2.0.1','io.reactivex.rxjava2:rxjava:2.1.0'])

这样别的开发者就知道哪些库是有相关性的,在删除库的时候也更方便。

17.跳过task
Gradle每次构建时都执行了许多task,其中有一些task是不需要的,可以把它们都屏蔽掉,如下:

tasks.whenTaskAdded { task ->if (task.name.contains('AndroidTest') || task.name.contains('Test')) {task.enabled = false}
}

这样在build时就会跳过包含AndroidTest和Test关键字的task了。
NOTE:有时候自己也会写一些task或者引入一些gradle插件和task,通过这种方式可以简单的进行选择性的执行。

18.通过逻辑判断来跳过task
上面有提到过动态获得字段,但有些东西是在打包发布的时候用,有些则是在调试时用,需要区分不同的场景,定义不同的task。下面以通过“以git的commit号当做版本号”这个需求做例子:

def cmd = 'git rev-list HEAD --first-parent --count'
def gitVersion = cmd.execute().text.trim().toInteger()
android {defaultConfig {versionCode gitVersion}
}

因为上面的操作可能比较慢,或者在debug时没必要,所以就做了如下判断:

def gitVersion() {if (!System.getenv('CI_BUILD')) { // 不通过CI进行build的时候返回1return 1    //1无实际意义,return用于中断后续操作}def cmd = 'git rev-list HEAD --first-parent --count'cmd.execute().text.trim().toInteger()
}
android {defaultConfig {versionCode gitVersion()}
}

这里用到了System.getenv()方法,可以参考Java中System下的getenv(),就是得到当前的环境。

19.引用全局的配置文件
在根目录中建立一个config.gradle文件:

ext {android = [compileSdkVersion: 23,applicationId    : "com.zyr.gradle",]dependencies = ["support-v7": "com.android.support:appcompat-v7:24.2.1",]
}

然后在顶层的build.gradle中引入apply from: “config.gradle”,即:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "config.gradle" // 引入该文件
buildscript {repositories {jcenter()}dependencies {classpath 'com.android.tools.build:gradle:2.3.3'}// ...
}

之后就可以在其余的build.gradle中读取变量了:

defaultConfig {applicationId rootProject.ext.android.applicationId // 引用applicationIdminSdkVersion 14targetSdkVersion 20
}
dependencies {compile rootProject.ext.dependencide["support-v7"] // 引用dependencide
}

20.区分不同环境下的不同依赖
除了通过buildtype来定义不同的依赖外,还可以通过写逻辑判断来做:
先在gradle.properties中写上:
needExample = true
然后在module的build.gradle中使用:

dependencies {//根据是不同情形进行判断if (!needExample) {provided fileTree(dir: 'libs', include: ['*.jar'])} else {compile 'com.android.support:example:1.0.0'}// ...
}

21.动态改变module种类
插件化有可能会要根据环境更改当前module是app还是lib:
先在gradle.properties中写上:
isDebug = false
然后在module的build.gradle中使用:

if (isDebug.toBoolean()) {apply plugin: 'com.android.application'
} else {apply plugin: 'com.android.library'
}

22.定义库的私有混淆(针对库的开发)
有很多库是需要进行混淆配置的,但让库的使用者配置混淆文件的方式总是不太友好,consumerProguardFiles可以让库的作者在库中定义混淆参数,让使用者无需了解其混淆:

apply plugin: 'com.android.library'
android {compileSdkVersion 24buildToolsVersion '24.0.2'defaultConfig {minSdkVersion 9targetSdkVersion 24consumerProguardFiles 'consumer-proguard-rules.pro' //  自定义混淆配置}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}

其中的consumer-proguard-rules.pro文件位置如下图:

consumerProguardFiles.jpg
打包工具会将*.pro文件打包进入aar中,库混淆的时候会自动使用此混淆配置文件。
以consumerProguardFiles方式加入的混淆具有以下特性:

*.pro文件会包含在aar文件中
这些pro配置会在混淆的时候被使用
此配置针对此aar进行混淆配置
此配置只对库文件(apply plugin: 'com.android.library)有效,对应用程序(apply plugin: ‘com.android.application’)无效
23.指定资源目录
在module的build.gradle中通过下面的配置,可以自定义java代码和res资源的目录,一个和多个都可以,更加灵活:

android {sourceSets {main {manifest.srcFile 'AndroidManifest.xml'java.srcDirs = ['src']resources.srcDirs = ['src']aidl.srcDirs = ['src']renderscript.srcDirs = ['src']assets.srcDirs = ['assets']if (!IS_USE_DATABINDING) { // 如果用了databindingjniLibs.srcDirs = ['libs']res.srcDirs = ['res', 'res-vm'] // 多加了databinding的资源目录} else {res.srcDirs = ['res']}}test {java.srcDirs = ['test']}androidTest {java.srcDirs = ['androidTest']}}
}

24.定义多个Manifest
在module的build.gradle中:

sourceSets {main {if (isDebug.toBoolean()) {manifest.srcFile 'src/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/release/AndroidManifest.xml'}}
}

根据flavor也可以进行定义:

productFlavors {abc {manifest.srcFile 'abc/AndroidManifest.xml'}main {manifest.srcFile '/AndroidManifest.xml'}
}

相关文章:

Android中Gradle常用配置

前言 本文记录了一些常用的gradle配置,基本上都是平时开发中可能会使用到的,如果有新内容会不定时更新,附官网 1.依赖库版本写法 不推荐写法: dependencies {compile com.example.code.abc:def:2. // 不推荐的写法 }这样写虽然可…...

Linux操作系统3-文件与IO操作2(文件描述符fd与文件重定向)

上篇文章:Linux操作系统3-文件与IO操作1(从C语言IO操作到系统调用)-CSDN博客 本篇代码Gitee仓库:myLerningCode 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 本篇重点:文件描述符fd与文件重定向 目录 一. 文件描述…...

k8s调度策略

调度策略 binpack(装箱策略) Binpacking策略(又称装箱问题)是一种优化算法,用于将物品有效地放入容器(或“箱子”)中,使得所使用的容器数量最少,Kubernetes等集群管理系…...

uniapp中父组件传参到子组件页面渲染不生效问题处理实战记录

上篇文件介绍了,父组件数据更新正常但是页面渲染不生效的问题,详情可以看下:uniapp中父组件数组更新后与页面渲染数组不一致实战记录 本文在此基础上由于新增需求衍生出新的问题.本文只记录一下解决思路. 下面说下新增需求方便理解场景: 商品信息设置中添加抽奖概率设置…...

螺丝螺帽缺陷检测识别数据集,支持yolo,coco,voc三种格式的标记,一共3081张图片

螺丝螺帽缺陷检测识别数据集,支持yolo,coco,voc三种格式的标记,一共3081张图片 3081总图像数 数据集分割 训练组90% 2781图片 有效集7% 220图片 测试集3% 80图片 预处理…...

一个简单带颜色的Map

越简单 越实用。越少设计,越易懂。 需求背景: 创建方法,声明一个hashset, 元素为 {“#DE3200”, “#FA8C00”, “#027B00”, “#27B600”, “#5EB600”} 。 对应的key为 key1 、key2、key3、key4、key5。 封装该方法&#xff0c…...

kubeadm安装K8s集群之基础环境配置

系列文章目录 1.kubeadm安装K8s集群之基础环境配置 2.kubeadm安装K8s集群之高可用组件keepalivednginx 3.kubeadm安装K8s集群之master节点加入 4.kubeadm安装K8s集群之worker1节点加入 kubeadm安装K8s集群基础环境配置 1.首先确保所有机器可以通信,然后配置主机host…...

前端实现在线预览excel文件

在前端开发中,经常会遇到需要在线预览各种文件的需求。本文将介绍如何使用前端技术实现在线预览 Excel 文件的功能。 一、基于微软office服务的excel预览 获取要预览的 Excel 文件的 URL(例如存储在 OneDrive 或 SharePoint 上的文件)。 使…...

关于idea-Java-servlet-Tomcat-Web开发中出现404NOT FOUND问题的解决

在做web项目时,第一次使用servlet开发链接前端和后端的操作,果不其然,遇到了诸多问题,而遇到最多的就是运行项目打开页面时出现404NOT FOUND的情况。因为这个问题我也是鼓捣了好久,上网查了许多资料才最终解决&#xf…...

SCRM私域流量管理工具助力企业微信电商转型升级

内容概要 在当今数字化时代,SCRM(社交客户关系管理)私域流量管理工具正逐渐成为企业转型的重要助力。尤其是在电商领域,企业微信的兴起为许多公司打开了新的销售渠道,通过SCRM系统的高效整合,企业能够更加…...

三相异步电动机为什么能够旋转?

三相异步电动机,作为一种广泛应用于工业、农业及其他领域的电动机,其工作原理的理解对于工程技术人员以及相关从业者来说至关重要。 一、三相异步电动机的基本结构 三相异步电动机主要由定子、转子和机壳组成。定子是电动机的静止部分,包含…...

优化移动端H5:常见问题与解决方案

移动端H5开发中的“坑”与解决方案 本文介绍了开发中遇到的几个关于移动端H5开发中的小问题,以及解决的方法。 一、iOS滑动不流畅问题 在iOS设备上,H5页面的滑动效果有时会出现不流畅的情况,特别是在页面高度超过一屏时。这通常是由于iOS的…...

TM1不藏私系列——#10. TM1快速运算的秘密武器-Feeder

与其他BI产品对比,TM1的快速运算能力一骑绝尘。 但是在多维度的数据组合下,TM1是依据什么进行运算的呢? 今天将和大家一同了解TM1快速运算的秘密武器-Feeder。 上期我们提到通过配置维度中的元素权重,可以在合并层级加总计算。除…...

【Python】【Conda 】Conda vs venv:Python开发者的虚拟环境选择指南

目录 引言一、概述1.1 Conda 虚拟环境1.2 Python venv 虚拟环境 二、安装与设置2.1 安装 Conda 虚拟环境2.2 安装 Python venv 虚拟环境 三、依赖管理3.1 Conda 依赖管理3.2 Python venv 依赖管理 四、适用场景五、性能与资源占用5.1 Conda 性能与资源占用5.2 Python venv 性能…...

【从0学英语】06.时态 - 一般过去时

一般过去时(Past Simple Tense)是表达过去发生的动作、状态或事实的核心时态。这一时态都扮演着不可或缺的角色,本篇文章将全面讲解一般过去时的定义、结构、用法以及常见的动词变化,通过例句和详细的解释帮你理解这一时态。 文章…...

获取cpu序列号-python实现

DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” -------------------------------------------------------------…...

文献分享: PLAID——为ColBERT架构设计的后期交互驱动器

👉前情提要: 神经网络自然语言模型概述 Transformer \text{Transformer} Transformer与注意力机制概述 📚相关论文: BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding \text{BERT: Pre-train…...

IMX6ULL开发板、PC机上的USB网卡、VMware中的Ubuntu的桥接网卡三者互Ping设置及设置

连上PC机上的USB网卡配置 首先打开Windows设备管理器,截图记录下当前的网络适配器,作为插上USB网卡后的对比: 然后打开“更改适配器选项”,也截张图,作为插上USB网卡后的对比: 插上USB网口&#xff0…...

孚盟云 MailAjax.ashx SQL漏洞复现

0x01 产品描述: ‌孚盟云‌是由...

前端 mp4 视频改成 m3u8 流模式

前端 mp4 视频改成 m3u8 流模式 mp4 视频的问题 1、mp4 视频通常对应一个文件,播放时需要加载全部文件,消耗网络资源。如果用户从中间某个时间访问,也会从头开始下载,浪费服务器性能。 2、mp4 视频文件容易被用户下载到本地。有…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

AspectJ 在 Android 中的完整使用指南

一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...