前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gradle for Android简要指南

Gradle for Android简要指南

作者头像
Anymarvel
发布2018-10-22 11:36:13
7600
发布2018-10-22 11:36:13
举报
文章被收录于专栏:Android开发实战Android开发实战

前言 Android官网构建系统介绍https://developer.android.com/studio/build/index.html

Gradle 是 Android 现在主流的编译工具,虽然在Gradle 出现之前和之后都有对应更快的编译工具出现,但是 Gradle 的优势就在于它是亲儿子,Gradle 编译比较慢,这和它的编译过程有关,但是最近伴随着 Android Studio2.0的发布(目前官网最新gradle 为2.2.0), Gradle 也进行了一次非常大的升级,叫Instant Run.它的编译速度网上有人用逆天两个字来形容。(虽然目前有 Bug 我们要相信,他会好的) 对于一些比较复杂的,特别是多人团队合作的项目我们会需要一些个性化的配置来提高我们的开发效率。一些高级功能需要我们手动的去配置gradle脚本。 按官网流程一一介绍,有疏漏的请留言,我们一起学习 首先来张大图

Paste_Image.png

对于一个典型的Android应用程序模块构建过程,遵循以下一般步骤:

1. 编译器转换你的源代码转换成DEX(Dalvik的可执行文件)的文件,其中包括Android设备上运行的字节码,和其他一切编译资源。

2. 该APK包装结合了DEX文件,资源编译成一个单一的APK。之前可以安装你的应用程序并部署到Android设备,但是,APK必须签名。

3. 该APK打包签署使用Debug或发布密钥库您的APK: a. 如果您正在构建您的应用程序,这是一个调试版本,应用程序你打算仅用于测试和分析后,打包签署您的应用程序与调试密钥库。Android Studio中自动配置与调试密钥库的新项目。 b. 如果您正在构建您的应用程序,你要在外部释放的发行版中,打包签署您的应用程序一起发布密钥库。要创建一个发布密钥库,了解Android Studio中签署您的应用程序。

4. 产生最终的APK之前,打包使用zipalign工具来优化您的应用程序在设备上运行时,使用较少的内存。

在构建过程的最后,您有一张调试APK或释放您的应用程序,你可以用它来部署,测试或释放到外部用户的APK。

以上是官网对apk打包过程的一个简要概括,我们根据官网对gradle进行一个简单的介绍:

1. Build Types 定义了编译类型,针对每个类型我们可以有不同的编译配置,不同的编译配置对应的有不同的编译命令。默认的有debug、release 的类型。

代码语言:javascript
复制
buildTypes {
   release {
       minifyEnabled true
       proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
   }

   debug {
       applicationIdSuffix ".debug"
   }

2. Product Flavors 如果我们需要针对同一份源码编译不同的程序(包名也不同),比如 免费版和收费版。我们就需要Product flavors。 注意,Product flavorsBuild Type是不一样的,而且他们的属性也不一样。所有的 product flavor 版本和defaultConfig 共享所有属性! 像Build type 一样,product flavor 也可以有自己的source set 文件夹。除此之外,product flavor 和 build type 可以结合,他们的文件夹里面的文件优先级甚至高于 单独的built type 和product flavor 文件夹的优先级。如果你想对于 blue类型的release 版本有不同的图标,我们可以建立一个文件夹叫blueRelease ,注意,这个顺序不能错,一定是 flavor+buildType 的形式。

代码语言:javascript
复制
productFlavors {
     demo {
         applicationId "com.example.myapp.demo"
         versionName "1.0-demo"
     }
     full {
         applicationId "com.example.myapp.full"
         versionName "1.0-full"
     }
 }

3. Build Variants 在开发中我们可能会有这样的需求: -- 我们需要在debug 和 release 两种情况下配置不同的服务器地址; -- 当打市场渠道包的时候,我们可能需要打免费版、收费版,或者内部版、外部版的程序。 -- 渠道首发包通常需要要求在欢迎页添加渠道的logo。等等 -- 为了让市场版和debug版同时存在与一个手机,我们需要编译的时候自动给debug版本不一样的包名。 这些需求都需要在编译的时候动态根据当前的编译类型输出不同样式的apk文件。这时候就是我们的buildType大展身手的时候了。

4. Manifest Entries 您可以在构建变量的配置清单文件的一些属性的值。这些构建值清单文件覆盖现有值。如果您想为您的模块,其中每个APK文件有不同的应用程序名称,最小的SDK版本,或目标SDK版本多个APK这是非常有用的。

代码语言:javascript
复制
defaultConfig {/**
 * applicationId uniquely identifies the package for publishing.
 * However, your source code should still reference the package name
 * defined by the package attribute in the main/AndroidManifest.xml file.
 */applicationId 'com.example.myapp'// Defines the minimum API level required to run the app.minSdkVersion 14// Specifies the API level used to test the app.targetSdkVersion 23// Defines the version number of your app.versionCode 1// Defines a user-friendly version name for your app.versionName "1.0"}

5. Dependencies 构建系统管理从本地文件系统,并从远程仓库项目的依赖。这可以使您不必手动搜索,下载和你的依赖的二进制包拷贝到你的项目目录 。这里提供下marven仓库的搜索地址:http://search.maven.org/ 不用访问外国网站也可以的哦

代码语言:javascript
复制
android {...}
...
dependencies { // The 'compile' configuration tells Gradle to add the dependency to the
 // compilation classpath and include it in the final package.

 // Dependency on the "mylibrary" module from this project
 compile project(":mylibrary") // Remote binary dependency
 compile 'com.android.support:appcompat-v7:23.4.0'

 // Local binary dependency
 compile fileTree(dir: 'libs', include: ['*.jar'])
}

6. Signing 如果我们打包市场版的时候,我们需要输入我们的keystore数据。如果是debug 版本,系统默认会帮我们配置这些信息,秘钥在home/.android/debug.keystore。这些信息在gradle 中都配置在signingConfigs中。

代码语言:javascript
复制
android {
 signingConfigs {
     config {
         keyAlias keystoreProperties['keyAlias']
         keyPassword keystoreProperties['keyPassword']
         storeFile file(keystoreProperties['storeFile'])
         storePassword keystoreProperties['storePassword']
     }
 } ...}

7. ProGuard 构建系统使您可以指定每个构建变量不同ProGuard的规则文件。构建系统可以运行ProGuard的构建过程中缩小和模糊处理的类。说白了,就是在gradle中进行混淆配置

代码语言:javascript
复制
android {
 buildTypes {     release {
         minifyEnabled true
         proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
                 'proguard-rules.pro'
     }
 }
 ...
}

Note: Android Studio disables ProGuard when using Instant Run.

8. APK Splits 构建系统可以自动建立不同的APK,每个只包含代码,需要一个特定的屏幕密度或应用程序二进制接口(ABI)的资源。

代码语言:javascript
复制
android {
...
splits { // Configures screen density split settings
 density {   // Enables density APK splits
   enable true

   // Specifies a list of screen densities Gradle should not create APK splits for
   exclude "ldpi", "xxhdpi", "xxxhdpi"

   // Specifies a list of compatible screen size settings for the manifest
   compatibleScreens 'small', 'normal', 'large', 'xlarge'
 }
}
}

当启动一个新的项目,Android的Studio会自动创建一些这些文件对你来说,并填充它们基于合理的默认值。

Paste_Image.png

1. The Gradle Settings File

2. The Top-level Build File

3. The Module-level Build File

4. Gradle Properties Files 目录结构及gradle详细说明官网都说的很清晰 https://developer.android.com/studio/build/index.html#build-files, 掌握了以上的基本结构和基本写法,简单的Android工程构建基本上不会有什么问题了 有gradle语法不了解的童鞋可直接查看官网代码 https://docs.gradle.org/current/userguide/userguide.html 很庞大知识体系,接下来我们稍微了解一些与Android相关的gradle进阶应用

Gradle脚本不是像传统的xml文件那样,而是一种基于Groovy的动态DSL,而Groovy语言是一种基于jvm的动态语言。

Project和tasks 在grade中的两大重要的概念,分别是project和tasks。每一次构建都是有至少一个project来完成,所以Android studio中的project和Gradle中的project不是一个概念。每个project有至少一个tasks。每一个build.grade文件代表着一个project。tasks在build.gradle中定义。当初始化构建进程,gradle会基于build文件,集合所有的project和tasks,一个tasks包含了一系列动作,然后它们将会按照顺序执行,一个动作就是一段被执行的代码,很像Java中的方法。 构建的生命周期 一旦一个tasks被执行,那么它不会再次执行了,不包含依赖的Tasks总是优先执行,一次构建将会经历下列三个阶段:

Paste_Image.png

生命周期事件可以在指定的生命周期之前、之中或者之后发生,在执行阶段之后发生的生命周期事件就该是构建的完成了。假设你希望在构建失败时能够在开发阶段尽早得到反馈,给构建生命周期事件添加回调有两种方法:一是通过闭包,二是实现Gradle API的一个监听接口,Gradle并没有要求你监听生命周期事件,这完全决定于你,通过监听器实现的优势就是可以给你的类写单元测试,看看下面这幅图会有一点直观的印象:

Paste_Image.png

在配置阶段,Gradle决定在任务在执行阶段的执行顺序,依赖关系的内部结构是通过直接的无环图(DAG)来表示的,图中的每一个任务称为一个节点,每一个节点通过边来连接,你很有可能通过dependsOn或者隐式的依赖推导来创建依赖关系。记住DAG图从来不会有环,就是说一个已经执行的任务不会再次执行,下面这幅图将要的展示了这个过程:

项目结构 和eclipse对比来看,Android studio构建的结构有很大的不同:

代码语言:javascript
复制
 MyApp
   ├── build.gradle
   ├── settings.gradle
   └── app
       ├── build.gradle
       ├── build
       ├── libs
       └── src
           └── main
               ├── java
               │   └── com.package.myapp
               └── res
                   ├── drawable
                   ├── layout
                   └── etc.

gradle使用了一个叫做source set的概念,官方解释:一个source set就是一系列资源文件,其将会被编译和执行。对于Android项目,main就是一个source set,其包含了所有的资源代码。当你开始编写测试用例的时候,你一般会把代码放在一个单独的source set,叫做androidTest,这个文件夹只包含测试。(此处不做测试开发可以不用了解) 使用Gradle Wrappe防止新版本迭代所导致的问题 grade只是一个构建工具,而新版本总是在更迭,所以使用Gradle Wrapper将会是一个好的选择去避免由于gradle版本更新导致的问题。Gradle Wrapper提供了一个windows的batch文件和其他系统的shell文件,当你使用这些脚本的时候,当前gradle版本将会被下载,并且会被自动用在项目的构建,所以每个开发者在构建自己app的时候只需要使用Wrapper。所以开发者不需要为你的电脑安装任何gradle版本,在mac上你只需要运行gradlew,而在windows上你只需要运行gradlew.bat。 在目录指定gradle插件版本

代码语言:javascript
复制
dependencies { classpath 'com.android.tools.build:gradle:1.2.3' }

,在项目的gradle/wrapper目录下面有个gradle-wrapper.properties中有如下内容:

代码语言:javascript
复制
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

修改URL也可以对gralde插件版本的控制。

关于gradle具体用法,我们后续再更新,gradle用法太杂,我们慢慢梳理 ?


Android历练记 是一个关于Android最新技术探讨,包含安全,架构,Android技术开发,ui绘制,源码解析等领域,如果你有兴趣,我们可以一起讨论学习, 关注微信公众号 Android历练记 或扫一扫二维码:

Android历练记

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android历练记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档