gradle 改造与优化小结

gradle 改造与优化小结

by hzwusibo 20180724

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

task:

《gradle 改造与优化小结》

标准的Android studio形式如下:

《gradle 改造与优化小结》

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

《gradle 改造与优化小结》

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

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

《gradle 改造与优化小结》
《gradle 改造与优化小结》

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

一、方便的全局设置

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

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

《gradle 改造与优化小结》

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

《gradle 改造与优化小结》

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

《gradle 改造与优化小结》
《gradle 改造与优化小结》

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

《gradle 改造与优化小结》
《gradle 改造与优化小结》

二、对gralde进行模块化分包

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

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

《gradle 改造与优化小结》

    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:

《gradle 改造与优化小结》

dependencies.gradle:

《gradle 改造与优化小结》

buildTypes.gradle:

《gradle 改造与优化小结》

三、使用gradle.properties

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

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

《gradle 改造与优化小结》

3.2、module使用以及注意事项

《gradle 改造与优化小结》
《gradle 改造与优化小结》

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

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

《gradle 改造与优化小结》
《gradle 改造与优化小结》

四、善用BuildConfig

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

buildConfigField 一共有3个参数,

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

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

第三个参数是常量值。

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

《gradle 改造与优化小结》

  BuildConfig.java 生成截图为:

《gradle 改造与优化小结》

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

config.gradle:

《gradle 改造与优化小结》

buildTypes.gradle:

《gradle 改造与优化小结》

五、依赖方式:

《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:

《gradle 改造与优化小结》

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这四个参数的意义,最近有些遗忘,所以查资料重新回顾了一下。

《gradle 改造与优化小结》

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的运行时问题。例如以下情况:

《gradle 改造与优化小结》

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

    原文作者:吴小博Toby
    原文地址: https://www.jianshu.com/p/7cb6bc11b633
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞