gradle 改造与优化小结

gradle 改造与优化小结

by hzwusibo 20180724

Q3    有个任务就是构建脚本gradle标准化

task:

标准的Android studio形式如下:

      参考了蜗牛和漫画的gradle, 对阅读的gradle也进行了改造,阅读项目是 myeclipse 时代升级而来, 不是标准的Android studio形式,只有一个 build.gradle。  全部的配置和打包配置 全部都写在了一起(标准的Android studio形式也存在这个问题),不利于后期的维护、查找、修改配置等, 而且gradle各种不同功能都写在一起,耦合比较大。

目标:把不同功能的 gradle拆成几个不同的grdle文件, 经常修改配置文件用全局配置形式。

结果:把原来的gralde拆成了  项目build.gradle、 app-build.gralde、  依赖包(walle-config.gradle (配置walle)、buildTypes.gradle(配置编译信息)、dependencies.gradle"(配置依赖))、channels.gradle(打包)、config.gralde(全局配置)

下面小结下改造与优化过程 ,并且回顾下gradle中的一些知识。

一、方便的全局设置

全局设置有一个好处,假设project里面存在多个application module, 这时候如果采用这种全局配置,可以达到一改应用多出的效果。  把一些固定的配置“拎”出来放到 config.gradle 中,这样以后直接更改 config.gradle 就行了,方便多人协作开发。(当然,如果有部分library module是想发布到jcenter,这时候可以定义一个针对library的配置文件,只需要要在library里面进行apply,这个可以完成独立的配置。不仅不会让本身的module更加笨重,并且配置会更清晰!)

1、新建一个全局配置的config.gradle,里面的内容为如下:

2、在project的build.gradle应用这个gradle配置

3、application中的build.gradle使用ext中的自定义常量,例如:

如果是Android studio标准的形式,可以在project根目录下自定义一个config.gradle(阅读gralde没有在根目录下,而且放到根目录比较麻烦,所以没有使用rootProject.ext.android形式)

二、对gralde进行模块化分包

          参照全局设置config.gradle, 我们也可以使用自定义 Gradle 文件,对gradle中不同的功能拆成多个gralde文件。接下来我们就动手来实践一下。

        2.1  在项目根目录下创建文件 channels.gradle, 把gralde中打包相关的内容都移到该gralde中,  顶部添加 apply plugin: 'com.android.application' 。

    2.2 然后在根目录下的 build.gradle 开头添加一句 apply from: "channels.gradle" 。  其他模块可以类似,gralde  可以拆成  app-build.gradle、  walle-config.gradle (配置walle)、buildTypes.gradle(配置编译信息)、dependencies.gradle"(配置依赖)channels.gradle(打包) 四块。

app-build.gradle:

dependencies.gradle:

buildTypes.gradle:

三、使用gradle.properties

      这个跟使用全局的gradle作用有点相似,区别就是全局的gradle是定义了ext,而gradle.properties则是直接提供配置参数。不过用法有点区别。

3.1、新建gradle.properties,并且写入一些配置参数

3.2、module使用以及注意事项

        很明显们看到了**as int 关键字,这是因为本来gradle.properties配置信息是字符串的格式,如果我们输入的常量是整形的时候,我们必须通过as int **进行类型转化。

          我们前面已经使用了全局gradle,gradle.properties用来存放签名信息。

四、善用BuildConfig

buildConfigField 这个会根据gradle的配置,在原来默认的BuildConfig.java基础上,动态添加一个指定数据类型的value。在程序中也是可以访问到的。

buildConfigField 一共有3个参数,

第一个是数据类型,就是你定义的常量值是一个什么类型,和Java的类型是对等的,这里是String。

第二个参数是常量名,这里是 STATE_TEST。

第三个参数是常量值。

如此定义之后,就会在BuildConfig.java中生成一个常量名为 STATE_TEST的常量定义。默认配置的生成是:

  BuildConfig.java 生成截图为:

可以结合全局变量,把一些经常要变得参数,写在全局变量config.gradle里面

config.gradle:

buildTypes.gradle:

五、依赖方式:

Compile(implementation):默认配置,该依赖会参与编译并且打包到所有的build type以及flavors的apk中

Provided:对所有的build type以及flavors来说只在编译时使用,只参与编译并不打包到最终apk

APK:只会打包到apk文件中而不参与编译,所以不能在代码中直接调用jar中的类或方法,否则在编译时会报错

另外三种compile只跟测试有关

Testcompile:仅仅是针对单元测试代码编译以及最终打包测试apk时有效,而对正常的debug或者release apk包不起作用。

Debug compile:仅仅针对debug模式的编译和最终的debug打包时有效。

Releasecompile:仅仅针对release模式的编译和最终的release打包时有效。

例如添加leakcanary在debug模式下,使用debugImplementation:


gralde基础知识可以去

 https://www.jianshu.com/p/2b8baf20059a

https://www.jianshu.com/p/25da4ef4c7a4


补充:  compileSdkVersion,minSdkVersion,targetSdkVersion,buildToolsVersion选取

使用Android Studio编写构建一个Android项目时,需要我们配置build.gradle文件,如下:

对于compileSdkVersion,minSdkVersion,targetSdkVersion和buildToolsVersion这四个参数的意义,最近有些遗忘,所以查资料重新回顾了一下。

1. compileSdkVersion

compileSdkVersion告诉Gradle用哪个Android SDK版本编译你的应用,使用任何新添加的API就需要使用对应Level的Android SDK。需要强调的是修改compileSdkVersion不会改变运行时的行为。当你修改了compileSdkVersion的时候,可能会出现新的编译警告、编译错误,但新的compileSdkVersion不会被包含到APK中:它纯粹只是在编译的时候使用。(我们需要尽量的修复这些警告)因此我们强烈推荐总是使用最新的SDK进行编译。在现有代码上使用新的编译检查可以获得很多好处,避免新弃用的API,并且为使用新的API做好准备。

2. minSdkVersion

minSdkVersion表示应用可以运行的最低要求。minSdkVersion是很多应用商用来判断用户设备是否可以安装某个应用的标志之一。如果设备的API低于minSdkVersion,那就安装不上该应用。在开发时minSdkVersion也起到一个重要角色:lint 默认会在项目中运行,它在你使用了高于minSdkVersion的API时会警告你,帮你避免调用不存在的API的运行时问题。例如以下情况:

Android Studio的提示,很明显,requestPermissions()只能在API大于等于23上的设备上才可以调用。那我们就针对该情况特殊处理:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

requestPermissions(new String[]{""}, REQUEST_CODE_ASK_CALL_PHONE);

} else {

// 不需要申请权限直接调用我们需要处理的方法。

}

当设备的版本号大于Android6.0,就调用requestPermissions(),否则就不做处理。

3. targetSdkVersion

三个版本号中最不同的就是targetSdkVersion了。targetSdkVersion是Android提供向前兼容的主要依据,在应用的targetSdkVersion没有更新之前系统不会应用最新的行为变化。这允许你在适应新的行为变化之前就可以使用新的API(因为你已经更新了compileSdkVersion不是吗?)。targetSdkVersion所暗示的许多行为变化都记录在VERSION_CODES文档中了,但是所有恐怖的细节也都列在每次发布的平台亮点中了,在这个API Level表中可以方便地找到相应的链接。例如,Android 6.0变化文档中谈了target为API 23时会如何把你的应用转换到运行时权限模型上,Android 4.4行为变化阐述了target为API 19及以上时使用set()和setRepeating()设置alarm会有怎样的行为变化。由于某些行为的变化对用户是非常明显的(弃用的menu按钮,运行时权限等),所以将target更新为最新的SDK是所有应用都应该优先处理的事情。但这不意味着你一定要使用所有新引入的功能,也不意味着你可以不做任何测试就盲目地更新 targetSdkVersion ,请一定在更新 targetSdkVersion 之前做测试。

一个Android系统,对外提供一套API,如何选择targetSdkVersion取决于应用程序需要实现的功能,如果你的应用程序使用API 7就可以实现的功能,可以不用考虑使用API 24,使用低版本API的其中一个好处,可以让更多的Android系统运行的效果保持一致,即兼容性更好,打个比方:API 7开发的APP可能兼容98%以上的Android手机,而API 24开发的APP可能兼容仅有60%,所谓的不兼容并不是无法正常运行,而是在不同Android系统的手机运行的效果差异比较大,会让用户感觉难以接受;使用低版本API的其中一个不足,显示的效果比较差,提供的可用的接口或类比较少,本来一句代码可以完成的功能(封装的类或接口),需要自己花一天琢磨写很多的代码,也就是有高版本API的其中一个原因,提供更多优雅的应用程序接口让开发者使用。

1). 系统版本高于targetSdkVersion

假设我们的targetSdkVersion是22(就是5.0)不需要动态申请权限,但是我们的系统是6.0的。现在程序运行到了需要某个需要权限的地方了。此时想想我们的手机该怎么办?系统逻辑是这样的:

final int targetSdkVersion= getApplicationContext().getApplicationInfo().targetSdkVersion;

if (targetSdkVersion < Build.VERSION_CODES.M) {

  // 这里的M就是level 23也就是6.0的系统

    // 这里的判断是如果当前的打包的targetSdkVersion小于23

  // 那么这里就不需要动态申请权限直接可以调取开放的权限

} else {

// 否则系统认为你需要动态申请权限

}

2). 系统版本等于targetSdkVersion

当安装app的时候targetSdkVersion刚好等需系统的level,这个时候Andorid平台会认为这个程序在此版本上已经经过了充分的测试。不必为此程序开启兼容性检查判断的工作了。也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。

3). 系统版本小于targetSdkVersion

还是举个例子:targetSdkVersion=23的时候,但是系统版本是22,很明显你在代码里面做了动态权限分配,但是系统版本不支持。之前minSdkVersion中的例子已经做了处理了。

4. buildToolsVersion

buildToolsVersion表示的是构建工具的版本号,规则是可以用高版本的构建工具来构建使用低版本SDK的工程。

5. minSdkVersion和targetSdkVersion与compileSdkVersion的其它区别

minSdkVersion和targetSdkVersion会被包含进最终的APK文件中,但是compileSdkVersion不会,如果你查看生成的AndroidManifest.xml文件,你会看到类似下面这样的标签:

参考资料:

1.https://developer.android.com/guide/topics/manifest/uses-sdk-element

2.https://blog.csdn.net/aa7704/article/details/50596998

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • Android组件化项目地址:Android组件化项目AndroidModulePattern Android组件...
    半灬边灬天阅读 2,921评论 4 37
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,129评论 25 707
  • 转载注明出处:http://www.jianshu.com/p/5255b100930e 0. 前言 完全由个人翻...
    王三的猫阿德阅读 2,516评论 0 4
  • 远山似墨 流水如琴 落花轻嗅 春水秋来 悠思谁解 绿水渡残花 共缠绵 蒙蒙烟雨 青石板苔痕斑布 脚印深深浅浅 白墙...
    慕光倾城阅读 347评论 2 4
  • 9月1日,开学的第一天,我观看了《开学第一课》,其中最让我感动的就是那个痴迷于中国汉字的外国叔叔理查德-西尔斯。网...
    牛广宇阅读 136评论 0 0