开发者社区> l1ka> 正文

第八章 自定义Android Gradle工程

简介: Android Gradle为我们提供了大量的DSL,我们使用这些DSL定义配置我们的工程以满足我们项目中不同的需求。这些DSL有很多,在上一章演示Android Gradle工程示例的时候,我们已经大概介绍了compileSdkVersion、buildToolsVersion以及defaultConfig等,这一章我们再详细介绍一些常用的DSL配置,这些配有有签名信息、构建类型、代码混淆、zipAlign对齐压缩等。
+关注继续查看

Android Gradle为我们提供了大量的DSL,我们使用这些DSL定义配置我们的工程以满足我们项目中不同的需求。这些DSL有很多,在上一章演示Android Gradle工程示例的时候,我们已经大概介绍了compileSdkVersion、buildToolsVersion以及defaultConfig等,这一章我们再详细介绍一些常用的DSL配置,这些配有有签名信息、构建类型、代码混淆、zipAlign对齐压缩等。


8.1 defaultConfig默认配置


defaultConfig是android对象中的一个配置块,负责定义所有的默认配置,它是一个ProductFlavor,如果一个ProductFlavor没有被特殊定义配置的话,默认就会使用defaultConfig{}块指定的配置,比如包名、版本号、版本名称等。


一个基本上的defaultConfig配置如下:


image.png

以上示例配置了Android 开发的基本信息,可以满足一个基本的Android App开发,下面我们对它的一些配置进行一个详细的说明。


8.1.1 applicationId


applicationId是ProductFlavor的一个属性,用于指定生成的App的包名,默认情况下是null,这时候在构建的时候,会从我们的AndroidManifest.xml文件中读取,也就是我们在AndroidManifest.xml文件中配置的manifest标签的package属性值。


8.1.2 minSdkVersion


minSdkVersion是ProductFlavor的一个方法,对应的方法原型是

public void minSdkVersion(int minSdkVersion) {
        this.setMinSdkVersion(minSdkVersion);
    }


它可以指定我们的App最低支持的Android 操作系统版本,其对应的值是Android SDK的API LEVEL,根据这里的方法原型,它接受的值是一个整数,除此之外,它还有以下两种方法原型定义:


image.png


根据我们前面讲的Gradle知识,发现minSdkVersion也是一个属性,它也可以接受一个字符串作为它的值,在这里明确一下,这个字符串不是我们SDK API LEVEL的字符串形式,而是Code Name,也就是我们的每个Android SDK或者说是Android OS的代号。就是我们新闻上经常见到的什么‘冰激凌三明治’什么的。这里给出一个列表,让大家一目了然。


image.png


8.1.3 targetSdkVersion


这个用于配置我们基于哪个Android SDK开发,它的可选值和minSdkVersion一样,没有配置的时候也会从AndroidManifest.xml文件中读取,参考minSdkVersion的介绍,这里就不多做介绍了。


8.1.4 versionCode


它也是ProductFlavor的一个属性,用于配置Android App的内部版本号,是一个整数值,通常用于版本的升级。没有配置的时候从AndroidManifest.xml文件中读取,建议配置。其方法原型是

public class DefaultProductFlavor extends BaseConfigImpl implements ProductFlavor {
    ...
    public ProductFlavor setVersionCode(Integer versionCode) {
        this.mVersionCode = versionCode;
        return this;
    }
    public Integer getVersionCode() {
        return this.mVersionCode;
    }
    ...
}


8.1.5 versionName


versionName和versionCode类似,也是ProductFlavor一个属性,用于配置Android App的版本名称,比如V1.0.0等等,主要显示用,让用户或者市场知道我们的Android App版本,它和versionCode一个是外部用,一个是内部使用,一起配合完成Android App的版本控制,其方法原型是


public ProductFlavor setVersionName(String versionName) {
        this.mVersionName = versionName;
        return this;
    }
    public String getVersionName() {
        return this.mVersionName;
    }


8.1.6 testApplicationId


用于配置测试App的包名,默认情况下是applicationId + “.test”,一般情况下默认即可,它也是ProductFlavor的一个属性,方法原型是

public ProductFlavor setTestApplicationId(String applicationId) {
        this.mTestApplicationId = applicationId;
        return this;
    }
    public String getTestApplicationId() {
        return this.mTestApplicationId;
    }


8.1.7 testInstrumentationRunner


用于配置单元测试时使用的Runner,默认使用的是android.test.InstrumentationTestRunner,如果你想使用自己自定义的Runner,修改这个值即可,它也是一个属性,其方法原型是

public ProductFlavor setTestInstrumentationRunner(String testInstrumentationRunner) {
        this.mTestInstrumentationRunner = testInstrumentationRunner;
        return this;
    }
    public String getTestInstrumentationRunner() {
        return this.mTestInstrumentationRunner;
    }


8.1.8 signingConfig


配置默认的签名信息,用对生成的App签名,它是一个SigningConfig,也是ProductFlavor的一个属性,可以直接对其进行配置,其方法原型是

public SigningConfig getSigningConfig() {
        return this.mSigningConfig;
    }
    public ProductFlavor setSigningConfig(SigningConfig signingConfig) {
        this.mSigningConfig = signingConfig;
        return this;
    }


8.1.9 proguardFile


用于配置App ProGuard混淆所使用的ProGuard配置文件,它是ProductFlavor的一个方法,接受一个文件作为参数。其方法原型为

public void proguardFile(Object proguardFile) {
        this.getProguardFiles().add(this.project.file(proguardFile));
    }


可以看到它可以被调用多次,调用一次添加一个,其参数被project.file方法转换为一个文件对象。其具体使用我们在稍后进行介绍。


8.1.10 proguardFiles


这个也是配置ProGuard配置文件,只不过它可以同时接受多个配置文件,因为它的参数是一个可变类型的参数。

public void proguardFiles(Object... files) {
        Object[] var2 = files;
        int var3 = files.length;
        for(int var4 = 0; var4 < var3; ++var4) {
            Object file = var2[var4];
            this.proguardFile(file);
        }
    }


从方法实现我们可以看到,同时可以添加多个ProGuard配置,在实际情况下中可以选择不同的配置方式。


8.2 配置签名信息


一个App只有被签名之后才能被发布、安装、使用,签名是保护App的方式,标记该App的唯一性,如果App被恶意篡改,签名就不一样了,就无法升级安装,一定程度上也保护了我们的App。


要对App进行签名,你先得有一个签名证书文件,这个文件被开发者持有,我们这里假设你已经有生成的证书,不对证书的生成进行介绍了。


一般我们的App有debug和release两种模式(下面会将构建类型),在我们开发调试的时候使用的是debug模式,发布的时候使用release模式;我们可以针对这两种模式采用不同的签名方式,一般debug模式的时候,Android SDK已经为我们提供了一个默认的debug签名证书,我们可以直接使用,但是发布的时候,release模式构建时,我们要配置使用自己生成的签名证书。


对于签名信息的配置,Android Gradle为我们提供了非常简便的方式,让我们可以非常容易的配置一个签名信息以供调用。


image.png


Android Gradle为我们提供了signingConfigs{}配置块便于我们生成多个签名配置信息。signingConfigs是android的一个方法,它接受一个域对象作为其参数,前面我们讲过的,其类型是NamedDomainObjectContainer<SigningConfig>,这样我们在signingConfigs{}块中定义的都是一个SigningConfig。一个SigningConfig就是一个签名配置,其可配置的元素如下:


  • storeFile 签名证书文件


  • storePassword 签名证书文件的密码


  • storeType 签名证书的类型


  • keyAlias 签名证书中密钥别名


  • keyPassword 签名证书中该密钥的密码


例子中我们定义配置了一个名为release的签名配置,除此之外,我们还可以配置多个不同的签名前置,比如我们添加一个debug的配置。


image.png


默认情况下,debug模式的签名已经被配置好了,使用的就是Android SDK自动生成的debug证书,它一般位于$HOME/.android/debug.keystore,其Key和密码都是已知的,一般情况下我们不需要单独配置debug模式的签名信息。


现在我们配置好了两个签名信息,但是他们还没有被使用,现在只是生成了两个SigningConfig的实例,一个变量名为release,一个为debug,如果要使用他们我们只需引用他们即可,比如在8.1.8节中我们讲配置默认的签名信息,现在我们就可以引用debug的配置信息使用。


image.png


可以看到我们在defaultConfig中对签名配置的应用这里的signingConfigs是android对象实例的一个属性,对应是getSigningConfigs(),debug就是我们上面创建的签名配置名称。


除了上面的默认签名配置之外,我们也可以对构建的类型分别配置签名信息,比如我上面说的debug模式配置debug的签名信息,release默认配置release的签名信息。


image.png


如果你还有其他类型,想为其配置单独的签名,也可以这么做,比如付费版的VIP,单独进行签名配置、特别的渠道包单独配置等等。


8.3 构建的应用类型


关于构建类型,前面的章节我们已经用到了一些,在Android Gradle工程中,Android Gradle已经帮我们内置了debug和release两个构建类型,他们两种模式的只要差别在于能否在设备上调试以及签名不一样,其他代码和文件资源都是一样的,一般情况下也够用了。


如果想增加新的构建类型,在buildTypes{}代码块中继续添加元素就好了。buildTypes和signingConfigs一样,也是android的一个方法,接受的参数也是一个域对象NamedDomainObjectContainer<BuildType>,添加的每一个都是BuildType类型,所以你可以使用BuildType提供的方法和属性对现有的BuildType配置,这里列举一些常用的配置。


8.3.1 applicationIdSuffix


applicationIdSuffix是BuildType的一个属性,用于配置基于默认applicationId的后缀,比如默认defaultConfig中配置的applicationId为org.flysnow.app.example82,我们在debug的BuildType中指定applicationIdSuffix为.debug,那么构建生成的debug apk的包名就是org.flysnow.app.example82.debug。其方法原型为

public BaseConfigImpl setApplicationIdSuffix(String applicationIdSuffix) {
        this.mApplicationIdSuffix = applicationIdSuffix;
        return this;
    }


8.3.2 debuggable


debuggable也是BuildType的一个属性,用于配置是否生成一个可供调试的Apk。其值可以为true或者false。其方法原型为

public BuildType setDebuggable(boolean debuggable) {
        this.mDebuggable = debuggable;
        return this;
    }


8.3.3 jniDebuggable


jniDebuggable和debuggable类似,也是BuildType的一个属性,用于配置是否生成一个可供调试Jni(C/C++)代码的Apk。接受boolean类型的值


8.3.4 minifyEnabled


也是BuildType的一个属性,用于配置该BuildType是否启用Proguard混淆,接受一个boolean类型的值

8.3.5 multiDexEnabled


也是BuildType的一个属性,用于配置该BuildType是否启用自动拆分多个Dex的功能,一般用于代码太多,超过了65535个方法的时候,进行的拆分为多个Dex的处理,后面会详细讲使用。接受一个boolean类型的值

8.3.6 proguardFile


是BuildType的一个方法,用于配置Proguard混淆使用的配置文件,和前面讲的defaultConfig中的proguardFile一样


8.3.7 proguardFiles


是BuildType的一个方法,用于配置Proguard混淆使用的配置文件,该方法可以同时配置多个Proguard配置文件

8.3.8 shrinkResources


是BuildType的一个属性,用于配置是否自动清理未使用的资源,默认为false.

这是一个非常有用的功能,我们在后面的章节会详细介绍。


8.3.9 signingConfig


配置该BuildType使用的签名配置,前面已经讲过,可以参考8.2章节温习一遍。


每一个BuildType都会生成一个SourceSet,默认位置为src/<buildtypename>/,根据我们以前讲的知识,一个SourceSet包含源代码、资源文件等信息,在Android中就包含了我们的java源代码,res资源文件以及AndroidManiftest文件等,所以针对不同的BuildType,我们可以单独的为其指定Java源代码,res资源等,只要把他们放到src/<buildtypename>/下相应的位置即可,在构建的时候,Android Gradle会优先使用他们代替我们main下的相关文件。


另外需要注意,因为我们的每个BuildType都会生成一个SourceSet,所以新增的BuildType名字一个要注意,不能是main和androidTest,因为他们两个已经被系统占用,同事每个BuildType之间名称不能相同。


除了会生成对应的SourceSet外,每一个BuildType还会生成相应的assemble<BuildTypeName>任务,比如我们常用的assembleRelease和assembleDebug就是Android Gradle自动生成的两个Task任务,他们是release和debug这两个BuildType自动创建生成的。执行相应的assemble<BuildTypeName>任务,就能生成对应BuildType的所有Apk。


8.4 使用混淆


代码混淆是一个非常有用的功能,它不仅可能优化我们的代码,让我们的Apk包变得更小,还可以混淆我们原来的代码,让反编译的人不容易看明白我们业务逻辑,很难分析。一般情况下我们发布到市场的版本一定是要混淆的,也就是我们的release模式编译的版本,但是我们自己调试的版本不用混淆,因为混淆后就无法断点跟踪调试了,也就是我们的debug模式。


要启用混淆,我们把BuildType的属性minifyEnabled的值设置为true即可。


现在我们启用了混淆,但是Android Gradle还不知道按何种规则进行混淆,不知道要保留哪些类不混淆,要做到这些就需要我们的Proguard配置文件了,现在我们为我们的混淆指定配置文件。


根据我们8.3小结讲的知识,指定Proguard配置文件我们可以使用proguardFile方法,也可以使用proguardFiles方法,这个根据情况而定,看你是想指定一个还是想同时指定多个。


这里我们注意到,使用了一个getDefaultProguardFile方法,该方法是android实例的一个方法,全限定写法可以这样android.getDefaultProguardFile,它的作用是获取我们Android SDK安装目录中,Android为我们提供的默认Proguard混淆配置文件,路径是Android SDK安装目录下的tools/proguard文件夹中,我们看下该方法的原型


image.png


从实现中看,我们只需传递一个文件名给这个方法,他就会返回tools/proguard目录下的该文件的绝对路径。


Android SDK默认为我们提供了两个Proguard配置文件,他们分别是proguard-android.txt和proguard-android-optimize.txt,一个是没有优化的,一个是优化的,你可以根据情况自己选择,当然你也可以都不用,全部自己定义,自己定义的时候可以参考Proguard官方网站文档,查看相关配置说明,网址为 http://proguard.sourceforge.net/


除了在BuildType中启用混淆和配置混淆外,我们也可以在defaultConfig中启用和配置,还记得我们前面在8.1章节讲的吧,因为这个是默认配置,一般用的比较少


我们还可以针对个别渠道,启用和配置Proguard混淆,多渠道包是通过productFlavors配置的,productFlavors是一个NamedDomainObjectContainer<ProductFlavor>域对象,其配置的渠道本质上就是一个ProductFlavor,和defaultConfig是一样的,所以每个渠道也可以单独的启用和配置Proguard混淆。


8.5 启用zipalign优化


zipalign是Android为我们提供的一个整理优化Apk文件的工具,它能提供系统和应用的运行效率,更快的读写Apk中的资源,降低内存的使用,所以对于我们要发布的App,在发布之前一定要使用zipalign进行优化


Android Gradle为我们提供了开启zipalign优化更简便的方式,我们只需要配置开启即可,剩下的操作,比如调用SDK目录下的zipalign工具进行处理等,Android Gradle会帮我们搞定。要为我们的release模式开启zipalign优化的话,只需进行如下配置即可。

zipAlignEnabled是BuildType的一个属性,接受一个boolean类型的值.


8.6 小结


这一章对我们Android Gradle常用的DSL做了详细的讲解说明,并且尽可能对常用的属性方法配置也进行了详细的说明,同时配有每个属性和方法的源代码实现,让大家对这些配置有个更深的认识。大家可以灵活的使用这些DSL对自己的项目进行自定义构建,以满足自己的项目需求。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
21362 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
23639 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
22513 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
14191 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
16702 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
23157 0
+关注
340
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载