Android Gradle studio配置各种问题集合 这一次彻底弄明白Gradle


 

问题:加快 Android 的 Gradle 构建

问题:把模块的公共的变量统一下

问题:如何立即停止编译?

修改打包后的输出目录
提高打包速度

 

 

 

Android工程中的Gradle

下面简述对我们工程最重要的几个Gradle文件,后续也会围绕他们进行详细讲解和补充

(请仔细看代码中的注释哈)

 

工程Project 中的 build.gradle : 工程控制Gradle编译配置

模块module中的 build.gradle : 控制每个Module的编译过程

gradle.properties : gradle动态参数的配置文件

local.properties : 本地的配置,如:SDK位置

gradle-wrapper.properties :gradle本地代理,声明了指向目录和版本

distributionUrl : 指定gradle版本不存在时,就从Value的地址中去下载。很多时候,我们只要版本换成我们本地存在的gradle版本就可以了

settings.gradle : 配置Gradle中的Module管理

 

 

常用Gradle Task

~ 表示 gradlew

gradlew是包装器,自动下载包装里定义好的gradle 版本,保证编译环境统一

gradle 是用本地的gradle

gradlew task -all : 罗列出所有Task ,同时携带具体作用和相互关系

gradlew assembleDebug : 导出所有渠道测试包

~ assembleRelease : 导出所有渠道正式包

~ assembleBaiduDebug --stacktrace : 导出指定渠道测试包,同时携带异常信息

~ --stop : 立即停止编译

~ check : 检查任务

~ build : 执行了 check和assemble

~ clean : 清除所有中间编译结果

————————————————

Gradle是一个构建工具,那么为什么要用构建工具,这就需要先从项目自动化开始讲起。

这个APK构建的过程主要分为以下几步:

1. 通过AAPT(Android Asset Packaging Tool)打包res资源文件,比如AndroidManifest.xml、xml布局文件等,并将这些xml文件编译为二进制,其中assets和raw文件夹的文件不会被编译为二进制,最终会生成R.java和resources.arsc文件。

2. AIDL工具会将所有的aidl接口转化为对应的Java接口。

3. 所有的Java代码,包括R.java和Java接口都会被Java编译器编译成.class文件。

4. Dex工具会将上一步生成的.class文件、第三库和其他.class文件编译成.dex文件。

5. 上一步编译生成的.dex文件、编译过的资源、无需编译的资源(如图片等)会被ApkBuilder工具打包成APK文件。

6. 使用Debug Keystore或者Release Keystore对上一步生成的APK文件进行签名。

7. 如果是对APK正式签名,还需要使用zipalign工具对APK进行对齐操作,这样应用运行时会减少内存的开销。

 

从以上步骤可以看出,APK的构建过程是比较繁琐的,而且这个构建过程又是时常重复的,如果没有构建工具,手动去完成构建工作,无疑对于开发人员是个折磨,也会产生诸多的问题,导致项目开发周期变长。

在Gradle出现之前,有三个基于Java的构建工具:Ant、Gant和Maven,它们被应用于Java或者Android开发中,我们来看看它们都有什么特点。

————————————————

3.2 采用了Groovy

Gradle这个基于Groovy的DSL,DSL(Domain Specifc Language)意为领域特定语言,只用于某个特定的领域。我们只要按照Groovy的DSL语法来写,就可以轻松构建项目。

Ant和Maven的构建脚本是由XML来编写的,如果XML逻辑复杂内容太多就不容易维护。Gradle可以使用Groovy来实现构建脚本,Groovy 是基于Jvm一种动态语言,它的语法和Java非常相似并兼容Java,因此你无需担心学习Groovy的成本。Groovy在Java的基础上增加了很多动态类型和灵活的特性,比起XML,Gradle更具有表达性和可读性。

 

Groovy的一些语法

————————————————

Gradle Wrapper

gradle-wrapper.properties 文件有一个简单的目的:决定在构建项目时使用哪个 Gradle 版本。它将随后会自动为你下载并保存该版本的 Gradle 。如果你在 Mac 上使用,运行下面命令 ls ~/.gradle/wrapper/dists/ 你就可以看到 Gradle Wrapper 曾为你下载过的所有 Gradle 版本。

 

#Mon Feb 17 10:44:51 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

 

 

3.配置Gradle Wrapper

gradle-wrapper.properties是Gradle Wrapper的属性文件,用来配置Gradle Wrapper,Gradle 4.2.1版本对应的gradle-wrapper.properties如下所示。

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

字段的含义如下:

  • distributionBase:Gradle解包后存储的主目录。
  • distributionPath:distributionBase指定目录的子目录。distributionBase+distributionPath就是Gradle解包后的存放位置。
  • distributionUrl:Gradle发行版压缩包的下载地址。
  • zipStoreBase:Gradle压缩包存储主目录。
  • zipStorePath:zipStoreBase指定目录的子目录。zipStoreBase+zipStorePath就是Gradle压缩包的存放位置。

这里我们最需要关注的是distributionUrl这个字段,如果官方的地址下载不了或者缓慢,可以将这个地址换为其他的镜像地址,或者干脆把Gradle发行版压缩包放在服务器上以供下载。

 

 

升级Gradle Wrapper有两种方式

一种是设置Gradle属性文件的distributionUrl属性

第二种是通过运行wrapper任务,推荐使用第二种方式

 

Gradle脚本是基于Groovy语言来编译执行的,在这之前最好要对Groovy语言有所了解。
重点:Task

在Gradle中一个原子性的操作叫做task,简单理解为task是Gradle脚本中的最小可执行单元。

依照惯例,我们从HelloWorld开始,新建一个build.gralde文件,创建2个task:

<span style="color:#000000"><span style="color:#cccccc"><code class="language-go">task helloWorld {
    doLast {
        <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"Hello World!"</span>
    }
}

task helloWorld2 <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"Hello World2!"</span>
}</code></span></span>
在命令行里执行命令:"gradle helloWorld helloWorld2",可以看到控制台输出:
<span style="color:#000000"><span style="color:#cccccc"><code class="language-css">> <span style="color:#f8c555">Task</span> :helloWorld
Hello World!

> <span style="color:#f8c555">Task</span> :helloWorld2
Hello World2!</code></span></span>

在 build.gradle 里可以通过 task 关键字来创建Task:

 
<span style="color:#000000"><span style="color:#cccccc"><code class="language-bash">task myTask(type: SomeType)</code></span></span>
 
实际的案例如下:
task hello {
    doLast {
        println 'Hello world!'
    }
}
ask(任务)和action(动作)是Gradle的重要元素。上面的代码中,task代表一个独立的原子性操作,比如复制一个文件,编译一次Java代码,这里我们简单的定义一个名为hello的任务。doLast 代表task执行的最后一个action,通俗来讲就是task执行完毕后会回调doLast中的代码,在上面这个例子中就会打印 ‘Hello world!’
 
上面的例子还可以写的更简洁一些,操作符<< 是doLast方法的快捷版本,它们做了相同的事情,如下所示。
task hello << {
    println 'Hello world!'
}
 
创建Task的几种常见写法
<span style="color:#000000"><span style="color:#cccccc"><code class="language-go">task myTask1 {
    doLast {
        <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task1"</span>
    }
}

task myTask2 <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task2"</span>
}

<span style="color:#999999">//采用 Project.task(String name) 方法来创建</span>
project.<span style="color:#f08d49">task</span>(<span style="color:#7ec699">"myTask3"</span>).doLast {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task3"</span>
}

<span style="color:#999999">//采用 TaskContainer.create(String name) 方法来创建</span>
project.tasks.<span style="color:#f08d49">create</span>(<span style="color:#7ec699">"myTask4"</span>).doLast {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task4"</span>
}

project.tasks.<span style="color:#f08d49">create</span>(<span style="color:#7ec699">"myTask5"</span>) <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task5"</span>
}</code></span></span>

创建Task的参数介绍

<span style="color:#000000"><span style="color:#cccccc"><code class="language-go">task myTask1 <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task1"</span>
}

task myTask2 <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task2"</span>
}

task myTask3 <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task3, this is old task"</span>
}

task <span style="color:#f08d49">myTask3</span>(description: <span style="color:#7ec699">"这是task3的描述"</span>, group: <span style="color:#7ec699">"myTaskGroup"</span>, dependsOn: [myTask1, myTask2], overwrite: <span style="color:#f08d49">true</span>) <span style="color:#67cdcc"><<</span> {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"doLast in task3, this is new task"</span>
}</code></span></span>

实战演习:

task clean(type: Delete) {
    delete rootProject.buildDir
}

Task增量构建

Gradle 支持一种叫做 up-to-date 检查的功能,也就是常说的增量构建。Gradle 的 Task 会把每次运行的结果缓存下来,当下次运行时,会检查输出结果有没有变更,如果没有变更则跳过运行,这样可以提高 Gradle 的构建速度。

 

重点:Project详解

1. Project类图

当构建进程启动后,Gradle基于build.gradle中的配置实例化org.gradle.api.Project类,先来看看 Project 类的主要结构(节选部分常用):

uploading.4e448015.gif转存失败重新上传取消

3. 文件操作

3.1 通过mkdir创建目录

<span style="color:#000000"><span style="color:#cccccc"><code class="language-bash">File mkDir = mkdir("${buildDir}/test");
File mkDir2 = mkdir("${buildDir}/test2")
println "检测目录是否创建成功:${mkDir.exists()}, ${mkDir2.exists()}"</code></span></span>

3.2 通过file、files 定位文件

<span style="color:#000000"><span style="color:#cccccc"><code class="language-dart"><span style="color:#999999">//定位单个文件,参数可以是相对路径、绝对路径</span>
File testDir <span style="color:#67cdcc">=</span> <span style="color:#f08d49">file</span>(<span style="color:#7ec699">"${buildDir}/test"</span>)
println <span style="color:#7ec699">"文件定位是否成功:${testDir.exists()}"</span>

<span style="color:#999999">//文件集合,Gradle里用 FileCollection 来表示</span>
FileCollection fileCollection <span style="color:#67cdcc">=</span> <span style="color:#f08d49">files</span>(<span style="color:#7ec699">"${buildDir}/test"</span>, <span style="color:#7ec699">"${buildDir}/test2"</span>)
println <span style="color:#7ec699">"-------对文件集合进行迭代--------"</span>
fileCollection.each {File f <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
    println f.name
}
println <span style="color:#7ec699">"-------文件迭代结束-------"</span>
<span style="color:#999999">//获取文件列表</span>
Set<span style="color:#67cdcc"><</span>File<span style="color:#67cdcc">></span> <span style="color:#cc99cd">set</span> <span style="color:#67cdcc">=</span> fileCollection.<span style="color:#f08d49">getFiles</span>()
println <span style="color:#7ec699">"文件集合里共有${set.size()}个文件"</span></code></span></span>

3.3 通过fileTree创建文件树

Gradle里用 ConfigurableFileTree 来表示文件树,文件树会返回某个目录及其子目录下所有的文件,不包含目录。

<span style="color:#000000"><span style="color:#cccccc"><code class="language-go"><span style="color:#999999">//先在build目录下创建3个txt文件</span>
<span style="color:#f08d49">file</span>(<span style="color:#7ec699">"${buildDir}/t1.txt"</span>).<span style="color:#f08d49">createNewFile</span>()
<span style="color:#f08d49">file</span>(<span style="color:#7ec699">"${buildDir}/test/t2.txt"</span>).<span style="color:#f08d49">createNewFile</span>()
<span style="color:#f08d49">file</span>(<span style="color:#7ec699">"${buildDir}/t1.java"</span>).<span style="color:#f08d49">createNewFile</span>()

<span style="color:#999999">//1.通过一个基准目录创建文件树,参数可以是相对目录,也可以是绝对目录,与file()方法一样</span>
<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"通过基准目录来创建文件树"</span>
ConfigurableFileTree fileTree1 <span style="color:#67cdcc">=</span> <span style="color:#f08d49">fileTree</span>(<span style="color:#7ec699">"build"</span>)
<span style="color:#999999">//添加包含规则</span>
fileTree1.include <span style="color:#7ec699">"*.txt"</span>, <span style="color:#7ec699">"*/*.txt"</span>
<span style="color:#999999">//添加排除规则</span>
fileTree1.exclude <span style="color:#7ec699">"*.java"</span>
fileTree1.each { f <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
    <span style="color:#cc99cd">println</span> f    
}

<span style="color:#67cdcc">/</span><span style="color:#67cdcc">/</span><span style="color:#f08d49">2.</span>通过闭包来创建文件树
<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"通过闭包来创建文件树"</span>
ConfigurableFileTree fileTree2 <span style="color:#67cdcc">=</span> <span style="color:#f08d49">fileTree</span>(<span style="color:#7ec699">"build"</span>) {
    include <span style="color:#7ec699">"*/*.txt"</span>, <span style="color:#7ec699">"*.java"</span>
    exclude <span style="color:#7ec699">"*.txt"</span>
}
fileTree2.each { f <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
    <span style="color:#cc99cd">println</span> f    
}

<span style="color:#999999">//3.通过map配置来创建文件树,可配置的选项有:dir: ''、include: '[]、exclude: []、includes: []、excludes: []</span>
<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"通过Map来创建文件树"</span>
def fileTree3 <span style="color:#67cdcc">=</span> <span style="color:#f08d49">fileTree</span>(dir: <span style="color:#7ec699">"build"</span>, includes: [<span style="color:#7ec699">"*/*.txt"</span>, <span style="color:#7ec699">"*.java"</span>])
fileTree3 <span style="color:#67cdcc">=</span> <span style="color:#f08d49">fileTree</span>(dir: <span style="color:#7ec699">"build"</span>, exclude: <span style="color:#7ec699">"*.java"</span>)
fileTree3.each { f <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
    <span style="color:#cc99cd">println</span> f    
}</code></span></span>

3.4 复制文件

复制文件需要使用复制任务(Copy)来进行,它需要指定要复制的源文件和一个目标目录,复制的规则都是定义在 CopySpec 接口里的,更详细的说明可参见 API 文档。

<span style="color:#000000"><span style="color:#cccccc"><code class="language-tsx">task <span style="color:#f08d49">testCopyFile</span>(<span style="color:#cc99cd">type</span>: Copy) {
    <span style="color:#999999">//复制build目录下的所有文件</span>
    <span style="color:#cc99cd">from</span> <span style="color:#7ec699">"build"</span>
    <span style="color:#999999">//复制单独的某个文件</span>
    <span style="color:#cc99cd">from</span> <span style="color:#7ec699">"test.java"</span>
    <span style="color:#999999">//复制某个文件树下的所有文件</span>
    <span style="color:#cc99cd">from</span> <span style="color:#f08d49">fileTree</span>(<span style="color:#7ec699">"build"</span>)

    include <span style="color:#7ec699">"*.txt"</span>
    include <span style="color:#7ec699">"*.java"</span>
    exclude <span style="color:#7ec699">"t1.txt"</span>
    <span style="color:#999999">//指定目标目录</span>
    into <span style="color:#7ec699">"outputs"</span>

    <span style="color:#999999">//对复制的文件重命名:通过闭包来映射</span>
    rename { fileName <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
        <span style="color:#999999">//增加 rename_ 前缀</span>
        <span style="color:#cc99cd">return</span> fileName.<span style="color:#f08d49">endsWith</span>(<span style="color:#7ec699">".java"</span>) <span style="color:#67cdcc">?</span> <span style="color:#7ec699">"rename_"</span> <span style="color:#67cdcc">+</span> fileName : fileName
    }

    <span style="color:#999999">//通过正则来映射文件名:abctest.java 会映射成 abchjy.java</span>
    rename <span style="color:#7ec699">'(.*)test(.*)'</span>, <span style="color:#7ec699">'$1hjy$2'</span>
}
</code></span></span>

3.5 删除文件

<span style="color:#000000"><span style="color:#cccccc"><code class="language-cpp"><span style="color:#999999">//删除 build 目录下所有文件</span>
<span style="color:#cc99cd">delete</span>(<span style="color:#7ec699">"${buildDir}"</span>)</code></span></span>
Gradle 就是通过 settings.gradle 来进行多项目构建的。

4.1 通过 settings.gradle 引入子项目

如图所示,在项目根目录创建一个 settings.gradle,在根目录、app以及library目录下也都创建一个 build.gradle 文件。
2.在 settings.gradle 里引入子项目
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-php"><span style="color:#cc99cd">include</span> <span style="color:#7ec699">":app"</span>, <span style="color:#7ec699">":library"</span></code></span></span></span>
3.在 build.gradle 里增加测试代码(添加打印)
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-go"><span style="color:#999999">//在根目录 build.gradle 里增加</span>
<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"-----root file config-----"</span>

<span style="color:#999999">//在 app/build.gradle 里增加</span>
<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"-----app config-----"</span>

<span style="color:#999999">//在 library/build.gradle 里增加</span>
<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"-----library config-----"</span></code></span></span></span>
读取步骤:

这是一个多项目构建的简单例子,可以看到结构与我们的 Android 项目是类似的。

Gradle 在运行时会读取并解析 settings.gradle 文件,生成一个 Settings对象,然后从中读取并解析子项目的 build.gradle 文件,

然后为每个 build.gradle 文件生成一个 Project 对象,进而组装一个多项目构建出来。

Settings 里最核心的API就是 include 方法,通过该方法引入需要构建的子项目。

4.2 项目配置

在根项目里可以对子项目进行配置:

 

<span style="color:#cccccc"><code class="language-dart"><span style="color:#999999">//通过path定位并获取该 Project 对象</span>
<span style="color:#f08d49">project</span>(path: String): Project
<span style="color:#999999">//通过path定位一个Project,并进行配置</span>
<span style="color:#f08d49">project</span>(path: String, config: Closure): Project

<span style="color:#999999">//针对所有项目进行配置</span>
<span style="color:#f08d49">allprojects</span>(config: Closure)
<span style="color:#999999">//针对所有子项目进行配置</span>
<span style="color:#f08d49">subprojects</span>(config: Closure)</code></span>

我们修改根目录 build.gradle 文件如下:

 

 

<span style="color:#cccccc"><code class="language-go"><span style="color:#cc99cd">println</span> <span style="color:#7ec699">"-----root file config-----"</span>

<span style="color:#999999">//配置 app 项目</span>
<span style="color:#f08d49">project</span>(<span style="color:#7ec699">":app"</span>) {
    ext {
        appParam <span style="color:#67cdcc">=</span> <span style="color:#7ec699">"test app"</span>
    }
}

<span style="color:#999999">//配置所有的项目</span>
allprojects {
    ext {
        allParam <span style="color:#67cdcc">=</span> <span style="color:#7ec699">"test all project"</span>
    }   
}

<span style="color:#999999">//配置子项目</span>
subprojects {
    ext {
        subParam <span style="color:#67cdcc">=</span> <span style="color:#7ec699">"test sub project"</span>
    }
}

<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"allParam = ${allParam}"</span></code></span>

ext是干嘛用的?

常见用法

在android的rootProject的build.gradle中,定义如下代码块
<span style="color:#000000"><span style="color:#cccccc"><code class="language-groovy">ext {
    compileSdkVersion = 25
    buildToolsVersion = "26.0.0"
    minSdkVersion = 14
    targetSdkVersion = 22
    appcompatV7 = "com.android.support:appcompat-v7:$androidSupportVersion"
}</code></span></span>
然后在app模块下,通过
<span style="color:#000000"><span style="color:#cccccc"><code class="language-groovy">rootProject.ext.compileSdkVersion
rootProject.ext.buildToolsVersion</code></span></span>
这种方式来访问在根目录build.gradle下定义的变量。
第二种用法:
implementation(name: 'WbCloudOcrSdk-pro-release-v2.2.29', ext: 'aar')

subprojects的用处

 

 

5. 构建脚本配置

5.1 buildscript

配置该 Project 的构建脚本的 classpath,在 Andorid Studio 中的 root project 中可以看到:

 

 

<span style="color:#cccccc"><code class="language-bash">buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
    }
}</code></span>

5.2 apply

我们通过该方法使用插件或者是其他脚本,options里主要选项有:

  • from: 使用其他脚本,值可以为 Project.uri(Object) 支持的路径
  • plugin:使用其他插件,值可以为插件id或者是插件的具体实现类

例如:

<span style="color:#404040"><span style="color:#cccccc"><code class="language-csharp"><span style="color:#999999">//使用插件,com.android.application 就是插件id</span>
apply plugin: <span style="color:#7ec699">'com.android.application'</span>
<span style="color:#999999">//使用插件,MyPluginImpl 就是一个Plugin接口的实现类</span>
apply plugin: MyPluginImpl

<span style="color:#999999">//引用其他gradle脚本,push.gradle就是另外一个gradle脚本文件</span>
apply <span style="color:#cc99cd">from</span>: <span style="color:#7ec699">'./push.gradle'</span></code></span></span>

6. 属性

6.1 Gradle属性

在与 build.gradle 文件同级目录下,定义一个名为 gradle.properties 文件,里面定义的键值对,可以在 Project 中直接访问。



 
<span style="color:#404040"><span style="color:#cccccc"><code class="language-cpp"><span style="color:#999999">//gradle.properties里定义属性值</span>
company<span style="color:#67cdcc">=</span><span style="color:#7ec699">"hangzhouheima"</span>
username<span style="color:#67cdcc">=</span><span style="color:#7ec699">"hjy"</span></code></span></span>
 

在 build.gradle 文件里可以这样直接访问:

<span style="color:#404040"><span style="color:#cccccc"><code class="language-bash">println "company = ${company}"
println "username = ${username}"</code></span></span>

6.2 扩展属性

还可以通过 ext 命名空间来定义属性,我们称之为扩展属性。

<span style="color:#404040"><span style="color:#cccccc"><code class="language-go">ext {
  username <span style="color:#67cdcc">=</span> <span style="color:#7ec699">"hjy"</span>
  age <span style="color:#67cdcc">=</span> <span style="color:#f08d49">30</span>
}

<span style="color:#cc99cd">println</span> username
<span style="color:#cc99cd">println</span> ext.age
<span style="color:#cc99cd">println</span> project.username
<span style="color:#cc99cd">println</span> project.ext.age</code></span></span>

Extension

Android的Extension

先看个 Android 的常规配置,以下是我的项目配置,截图如下所示:

uploading.4e448015.gif转存失败重新上传取消
我们重点看看 defaultConfig、productFlavors、signingConfigs、buildTypes 这4个内部 Extension对象是怎么定义的,
通过查看源码可以找到一个叫 BaseExtension 的类,里面的相关代码如下:

 

NamedDomainObjectContainer的使用场景

它定义了 debug、relase 两种打包模式:
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-csharp">android {

    buildTypes {
        release {
            <span style="color:#999999">// 是否开启混淆</span>
            minifyEnabled <span style="color:#cc99cd">true</span>
            <span style="color:#999999">// 开启ZipAlign优化</span>
            zipAlignEnabled <span style="color:#cc99cd">true</span>
            <span style="color:#999999">//去掉不用资源</span>
            shrinkResources <span style="color:#cc99cd">true</span>
            <span style="color:#999999">// 混淆文件位置</span>
            proguardFiles <span style="color:#f08d49">getDefaultProguardFile</span>(<span style="color:#7ec699">'proguard-android.txt'</span>), <span style="color:#7ec699">'proguard-rules.pro'</span>
            <span style="color:#999999">// 使用release签名</span>
            signingConfig signingConfigs.hmiou
        }

        debug {
            signingConfig signingConfigs.hmiou
        }
    }
}</code></span></span></span>
  1. debug、release 是可以修改成其他名字的,你可以替换成你喜欢的名字;

Android Gradle学习(七):Gradle构建生命周期

Gradle 进行构建,都要经过3个生命周期阶段:

  • 初始化阶段
  • 配置阶段
  • 执行阶段

Gradle 提供了很多生命周期监听方法,可以在各个阶段 Hook 指定的任务。

build.gradle 代码:
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-go"><span style="color:#999999">//对子模块进行配置</span>
subprojects { sub <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
    sub.beforeEvaluate { proj <span style="color:#67cdcc">-</span><span style="color:#67cdcc">></span>
        <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"子项目beforeEvaluate回调..."</span>
    }
}

<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"根项目配置开始---"</span>

task rootTest {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"根项目里任务配置---"</span>
    doLast {
        <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"执行根项目任务..."</span>
    }
}

<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"根项目配置结束---"</span></code></span></span></span>
app/build.gradle 代码:
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-go"><span style="color:#cc99cd">println</span> <span style="color:#7ec699">"APP子项目配置开始---"</span>

afterEvaluate {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"APP子项目afterEvaluate回调..."</span>
}

task appTest {
    <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"APP子项目里任务配置---"</span>
    doLast {
        <span style="color:#cc99cd">println</span> <span style="color:#7ec699">"执行子项目任务..."</span>
    }
}

<span style="color:#cc99cd">println</span> <span style="color:#7ec699">"APP子项目配置结束---"</span></code></span></span></span>
在根目录执行:gradle -q,结果如下:
<span style="color:#000000"><span style="color:#cccccc"><span style="color:#404040"><code class="language-undefined">根项目配置开始---
根项目里任务配置---
根项目配置结束---
子项目beforeEvaluate回调...
APP子项目配置开始---
APP子项目里任务配置---
APP子项目配置结束---
APP子项目afterEvaluate回调...</code></span></span></span>
现在,点击 Android Studio 右上角的 Gradle 标签
uploading.4e448015.gif转存失败重新上传取消

Gradle插件讲解

 
 
 
应用
1.学习各种组件
2.各种插件的东西和框架都要用
3.可以解决各种sdk集成的各种编译问题
 
---------------------------------------------------------------------------------------------------------------


实际遇到的问题解决办法:

The number of method references in a .dex file cannot exceed 64K.

api的含义:把架包提供出去。某一个架包也是可以用api的。

api 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:5.1.4'

 

问题:

multiDexEnabled true
显示你有2个版本,1.01和1.02版本。模块之间弄multi和项目之间multi

 

查看是否编译进去了

https://www.jianshu.com/p/24ebbbe434a4

 

参考博客:刘望舒

https://blog.csdn.net/itachi85/article/details/81906139


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值