《Gradle权威指南》--Android Gradle高级自定义
No1:
指定共享库
<uses-library
android:name="com.google.android.maps"
android:required="true"/>
No2:
android除了标准的sdk,还存在两种库
1)add-on库:位于add-ons目录下,大部分是第三方厂商或者公司开发的
2)optional可选库:位于platforms/android-xx/optional目录下,一般是为了兼容旧版本的API,比如HttpClient的org.apache.http.legacy
第一种Android Gradle会自动解析并添加到classpath里,第二种就不会
No3:
android{
useLibrary 'org.apache.http.legacy'
}
No4:
批量修改生成的apk文件名
android{
compileSdkVersion 23
buildToolsVersion "23.0.1"
useLibrary 'org.apache.http.legacy' defaultConfig{
applicationId "org.flysnow.app.example92"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes{
release{
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
zipAlignEnabled true
}
}
productFlavors{
google{ }
}
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.startsWith("_")?variant.flavorName.substring(1) : variant.flavorName
def apkFile = new File(output.outputFile.getParent(),"Example92_${flavorName}_v${variant.versionName}_${buildTime()}.apk")
output.outputFile = apkFile
}
}
}
} def buildTime{
def date = new Date()
def formattedDate = date.format('yyyyMMdd')
return formattedDate
}
每一个ApplicationVariant至少有一个或多个outputs输出
No5:
Android支持基于文件的模块化,就是apply from
version.gradle文件
ext{
appVersionCode = 1
appVersionName = "1.0.0"
}
build.gradle文件中引用
apply from: 'version.gradle'
No6:
获取当前的tag名称
git describe --abbrev=0 --tags
No7:
动态从git tag中获取应用的版本名称
def getAppVersionName(){
def stdout = new ByteArrayOutputStream()
exec{
commandLine 'git','describe','--abbrev=0','-tags'
standardOutput = stdout
}
return stdout.toString()
}
调用
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" defaultConfig{
applicationId "org.flysnow.app.example93"
minSdkVersion 14
targetSdkVersion 23
versionCode appVersionCode
versionName getAppVersionName()
}
}
No8:
以git tag的数量作为其版本号
def getAppVersionCode(){
def stdout = new ByteArrayOutputStream()
exec{
commandLine 'git','tag','--list'
standardOutput = stdout
}
return stdout.toString().split("\n").size()
}
调用
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" defaultConfig{
applicationId "org.flysnow.app.example93"
minSdkVersion 14
targetSdkVersion 23
versionCode getAppVersionCode()
versionName getAppVersionName()
}
}
No9:
隐藏签名文件信息(签名文件放在服务器,兼容debug打包)
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" 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") //当不能从环境变量里获取到签名信息的时候,就使用项目中带的debug签名
if(!appStoreFile||!appStorePassword||!appKeyAlias||!appKeyPassword){
appStoreFile = "debug.keystore"
appStorePassword = "android"
appKeyAlias = "androiddebugkey"
appKeyPassword = "android"
}
release{
storeFile file(appStoreFile)
storePassword appStorePassword
keyAlias appKeyAlias
keyPassword appKeyPassword
}
}
}
No10:
动态配置AndroidManifest文件
ManifestPlaceholders是ProductFlavor的一个属性,是一个Map类型,所以我们可以同时配置很多个占位符
<meta-data android:value="${UMENG_CHANNEL}" android:name="UMENG_CHANNEL"> android{
compileSdkVersion 23
buildToolsVersion "23.0.1" productFlavors{
google{
manifestPlaceholders.put("UMENG_CHANNEL","google")
}
baidu{
manifestPlaceholders.put("UMENG_CHANNEL","baidu")
}
}
}
它会把AndroidManifest文件中所有占位符变量为UMENG_CHANNEL的内容替换为manifestPlaceholders中对应的value的值
缩写
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" productFlavors{
google{}
baidu{}
} productFlavors.all{
flavor->manifestPlaceholders.put("UMENG_CHANNEL",name)
}
}
No11:
自定义你的BuildConfig
public final class BuildConfig{
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "org.flysnow.app.example96";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "baidu";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0.0";
}
获取当前包名
context.getPackageName()
//更方便,性能更快
BuildConfig.APPLICATION_ID
注:DEBUG常量在debug模式下的值是true,在release模式下自动变为false
新增一些常量
public void buildConfigField(@NonNull String type,@NonNull String name,@NonNull String value){}
第一个参数type是要生成字段的类型,第二个参数name是要生成字段的常量名字,第三个参数value是要生成字段的常量值。最终生成字段格式:<type> <name> = <value>
例:安装渠道包的时候打开相应的网页
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" defaultConfig{
applicationId "org.flysnow.app.example96"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName '1.0.0'
} productFlavors{
google{
buildConfigField 'String','WEB_URL','"http://www.google.com"'
}
baidu{
buildConfigField 'String','WEB_URL','"http://www.baidu.com"'
}
}
}
BuildConfig类就会生成相应的常量
public static final String WEB_URL = "http://www.baidu.com";
我们通过BuildConfig.WEB_URL使用即可,在打包的时候,Android Gradle会帮我们自动生成不同的值
No12:
动态添加自定义的资源
res/Values文件夹里可以使用xml方式定义,还可以在我们的Android Gradle中定义,实现这一功能的正是resValue方法
public void resValue(@NonNull String type,@NonNull String name,@NonNull String name,@NonNull String value){
ClassField alreadyPresent = getResValues().get(name);
if(alreadyPresent != null){
String flavorName = getName();
if(BuilderConstants.MAIN.equals(flavorName)){
logger.info("DefaultConfig:resValue '{}' value is being replaced: {} -> {}",name,alreadyPresent.getValue(),value);
}else{
logger.info("ProductFlavor({}):resValue'{}' value is being replaced:{} -> {}",flavorName,name,alreadyPresent.getValue(),value);
}
}
addResValue(AndroidBuilder.createClassField(type,name,value));
}
例:
android{
compileSdkVersion 23
buildToolsVersion "23.0.1"
productFlavors{
google{
resValue 'string','channel_tips','google渠道欢迎你'
}
baidu{
resValue 'string','channel_tips','baidu渠道欢迎你'
}
}
}
生成
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="channel_tips" translatable="false">baidu渠道欢迎你</string>
</resources>
No13:
Java编译选项
compileOptions来对Java编译选项进行配置
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" compileOptions{
encoding = 'utf-8'
sourceCompatibility = JavaVersion.VERSION_1_6
targetCompatibility = JavaVersion.VERSION_1_6
}
}
注:scourceCompatibility是配置Java源代码的编译级别,比如1.5/1.6这样
targetCompatibility是配置生成的Java字节码的版本
No14:
adb操作选项配置--adbOptions
public class AdbOptions implements com.android.builder.model.AdbOptions{
int timeOutInMs;
List<String> installOptions; @Override
public int getTimeOutInMs(){
return timeOutInMs;
} public void timeOutInMs(int timeOutInMs){
this.timeOutInMs(timeOutInMs);
} public void timeOutInMs(int timeOutInMs){
setTimeOutInMs(timeOutInMs);
} @Override
public Collection<String> getInstallOptions(){
return installOptions;
} public void setInstallOptions(String option){
installOptions = ImmutableList.of(option);
} public void setInstallOptions(String... options){
installOptions = ImmutableList.copyOf(options);
} public void installOptions(String option){
installOptions = ImmutableList.of(option);
} public void installOptions(String... options){
installOptions = ImmutableList.copyOf(options);
}
}
使用
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" adbOptions{
timeOutInMs = 5*1000//秒
installOptions '-r','-s'
}
}
adb install有六个选项:
-l:锁定该应用程序
-r:替换已存在的应用程序,就是强制安装
-t:允许测试包
-s:把应用程序安装到SD卡上
-d:允许进行降级安装,就是安装的程序比手机上带的版本低
-g:为该应用授予所有运行时的权限
No15:
Dex选项配置--dexOptions{}
package com.android.builder.core;
import com.android.annotation.Nullable; public interface DexOptions{
boolean getIncremental();
boolean getPreDexLibraries();
boolean getJumboMode();
@Nullable
String getJavaMaxHeapSize();
@Nullable
Integer getThreadCount();
}
incremental用来配置是否启用dx的增量模式
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" dexOptions{
incremental true
}
}
javaMaxHeapSize配置执行dx命令时为其分配的最大堆内存,主要用来解决执行dx时内存不够用的情况
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" dexOptions{
javaMaxHeapSize '4g'
}
}
jumboMode用来配置是否开启jumbo模式,解决函数数量超过65535个的问题
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" dexOptions{
jumboMode true
}
}
preDexLibraries用来配置是否预执行dex Libraries库工程,开启后会大大提高增量构建的速度,不过可能会影响clean构建的速度
threadCount用来配置Android Gradle运行dx命令时使用的线程数量,适当提高dx的效率
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" dexOptions{
threadCount 2
}
}
No16:
app方法数为什么有65535这个限制?
Dalvik虚拟机在执行DEX文件的时候,它使用了short这个类型来索引DEX文件中的方法,所以单个DEX文件可以被定义的方法最多只能是65535个。
No17:
Android 5.0之后,使用了ART的运行时方式,可以天然支持app有多个DEX文件。ART在安装app的时候执行预编译,把多个DEX文件合并成一个oat文件执行。
No18:
突破65535方法限制
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" defaultConfig{
applicationId "org.flysnow.app.example911"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName '1.0.0'
//启用multidex
multiDexEnabled true
}
}
dependencies{
compile fileTree(dir: 'libs',include:['*.jar'])
compile 'com.android.support:multidex:1.0.1'
}
1)如果没有自定义Application,直接使用MultiDexApplication
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.flysnow.app.example911">
<application
...
android:name="android.support.multidex.MultiDexApplication">
...
</application>
</manifest>
2)如果有自定义Application,直接继承MultiDexApplication即可
3)如果自定义Application继承了其他第三方提供的Application,就需要重写attachBaseContext方法
public class Example911Application extends Application{
@Override
protected void attachBaseContext(Context base){
super.attachBaseContext(base);
MultiDex.install(this);
}
}
因为继承MultiDexApplication也是通过重写attachBaseContext方法然后MultiDex.install(this)方法实现的
No19:
自动清理未使用的资源--Resource Shrinking
android{
compileSdkVersion 23
buildToolsVersion "23.0.1" buildTypes{
release{
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
}
}
避免误删--keep(文件位置:res/raw/keep.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"/>
只用中文的语言资源
android{
compileSdkVersion 23
buildToolsRevision "23.0.1" defaultConfig{
applicationId "org.flysnow.app.example912"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName '1.0.0'
resConfigs 'zh'
}
}
动清理资源只是在打包的时候,不打包到apk中,并没有删除工程中的资源
《Gradle权威指南》--Android Gradle高级自定义的更多相关文章
- 《Gradle权威指南》--Gradle插件
No1: 应用插件 apply plugin:'java' apply plugin:org.gradle.api.plugins.JavaPlugin apply plugin:JavaPlugin ...
- 《gradle权威指南》--Gradle入门
No1: Window下搭建Gradle:添加GRADLE_HOME环境变量,然后把GRADLE_HOME\bin添加到PATH系统变量里保存即可.完成后打开CMD,运行gradle -v来验证 No ...
- 《Gradle权威指南》--Gradle构建脚本基础
No1: 设置文件默认名是setting.gradle,放在根目录下,大多数作用都是为了配置子工程 No2: 一个Project包含很多个Task.Task就是一个操作,一个原子性的操作.其实它是Pr ...
- 《Gradle权威指南》--Gradle任务
No1: 多种方式创建任务 def Task ex41CreateTask1 = task(ex41CreateTask1) ex41CreateTask1.doLast{ println " ...
- 读书笔记--Android Gradle权威指南(上)
本篇文章已授权微信公众号 dasu_Android(大苏)独家发布 最近看了一本书<Android Gradle 权威指南>,对于 Gradle 理解又更深了,但不想过段时间就又忘光了,所 ...
- 读书笔记--Android Gradle权威指南(下)
前言 最近看了一本书<Android Gradle 权威指南>,收获挺多,就想着来记录一些读书笔记,方便后续查阅. 本篇内容是基于上一篇:读书笔记--Android Gradle权威指南( ...
- Gradle系列之Android Gradle高级配置
本篇文章主要在之前学习的基础上,从实际开发的角度学习如何对 Android Gradle 来进行自定义以满足不同的开发需求,下面是 Gradle 系列的几篇文章: Gradle系列之初识Gradle ...
- Gradle系列之Android Gradle插件
原文发于微信公众号 jzman-blog,欢迎关注交流. 通过前面几篇文章学习了 Gradle 基础知识以及 Gradle 插件相关的知识,关于 Gradle 及其插件相关知识请先阅读下面几篇文章: ...
- Gradle系列之Android Gradle基础配置
原文发于微信公众号 jzman-blog,欢迎关注交流. 通过前面几篇文章学习了 Gradle 基础知识以及 Gradle 插件相关的知识,关于 Gradle 及其插件相关知识请先阅读下面几篇文章: ...
- Android Gradle 构建工具(Android Gradle Build Tools)是什么?
转载地址:http://mrfu.me/android/2015/07/17/New_Android_Gradle_Build_Tools/ 译者地址:[翻]一览新的 Android Gradle 构 ...
随机推荐
- MySQL指令
在mysql里:文件夹就是数据库 文件就是表 创建用户: 格式:create user '用户名'@'IP地址' identified by '密码'; 说明:IP地址是用来限制用户只能在哪 ...
- json转对象-对象转json
我们经常会用到json,所以在c#里就会经常有对象or对象数组转json,json转对象or对象数组. ps:对象或者json可能是{}or[],也就是json属性or json数组形式,或者json ...
- mysql 原理~ 乐观锁和悲观锁
一 简介:今天咱们来聊聊悲观锁和乐观锁 二 悲观锁 1 定义 在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC” ...
- Sql Server 2008 数据库18456错误怎么解决?
可以windows连接,以前都可以,昨天突然就不可以用SQL连接,报18456错误. 1.以windows验证模式进入数据库管理器. 2.右击sa,选择属性: 在常规选项卡中,重新填写密码和确认密码( ...
- ARMV8 datasheet学习笔记3:AArch64应用级体系结构之Memory order
1.前言 2.基本概念 Observer 可以发起对memory read/write访问的都是observer; Observability 是一种观察能力,通过read可以感知到别的observe ...
- Qt5.8 在windows下mingw静态编译
官方对编译一些条件介绍:https://doc.qt.io/qt-5/windows-requirements.html 在默认情况下,用QtCreator编译程序时,使用的是动态编译.编译好的程序在 ...
- KVM -> 虚拟机在线热添加技术_04
热添加技术 1.KVM在线热添加硬盘
- mongodb数据库安装及常见操作
客户端和服务端的安装 # rpm -ivh mongo-10gen-2.4.6-mongodb_1.x86_64.rpm mongo-10gen-server-2.4.6-mongodb_1.x86_ ...
- ADC自动转接功能Lua实现
一.背景介绍: 虽然使用Mod_fifo和mod_callcenter可以做呼叫中心的应用,但在实现应用中,这两个模块很难客制化需求,再此我用Lua实现了5路客服(1000-1004),一个呼叫中心号 ...
- java.lang.NoClassDefFoundError: com/google/inject/Injector
报错如下: 解决方案: <dependency> <groupId>com.google.inject</groupId> <artifactId>gu ...