Gradle for Android 使用之旅之gradle的基础

Gradle Build Files in Android 第一章

Gradle for Android Basics

Android applications 使用gradle构建,gradle是一门高级语言并且广泛用于java中,提供的Android插件为Android apps开发提供了很多的功能,例如build types, flavors, signing configurations, library projects,更多可查看Android Plugin DSL Reference

1.1 Gradle Build Files in Android

问题

你想理解创建Android工程生成的build file

解决方案

创建一个新的Android工程并查看settings.gradle, build.gradle, 和 app/build.gradle.

分析

Android Studio 是官方提供开发Android projects 的IDE,通过Android Studio 向导Start a new Android Studio project创建第一个项目吧。

Start a new Android Studio project
Start a new Android Studio project

这一步就不多说了,相信大家都知道的。

然后我们看到一个默认的工程是怎么样的。

default project view
default project view

settings.gradle

Gradle 构建的Android工程是一个多项目工程,在settings.gradle中显示当前项目有哪些module。默认显示:

    include ':app'

如果这时我创建一个名为gradledemomodule 的library项目

new library
new library

settings.gradle会增加gradledemomodule,多个项目用,隔开,显示如下:

    include ':app', ':gradledemomodule'

project的build.gradle

    buildscript {
      repositories {
        jcenter()
      }
      dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
      }
    }

    allprojects {
      repositories {
        jcenter()
      }
    }

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

首先来看下buildscript节点,他是gradle脚本自身需要使用的资源,资源下载来自jcenter仓库,关于jcenterMaven单独去了解。jcenter目前是默认的,他兼容了Maven并且性能更优。然后在dependencies节点中声明了我们使用的gradle版本。

或许我们会以为allprojects中也同样声明了jcenter是否是重复了,其实不是的allprojects设置所有project默认的仓库来源,与buildscript作用范围是不一样的。

task clean声明了一个任务,任务类型是Delete(也可以是copy等),每当修改settings.gradle后同步则会删除rootProject.buildDir目录下所有。

app的build.gradle

    apply plugin: 'com.android.application'

    android {
      compileSdkVersion 24
      buildToolsVersion "23.0.3"

      defaultConfig {
        applicationId "com.branch.www.gradledemo"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
      }

      buildTypes {
        release {
          minifyEnabled false
          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
      }
    }

    dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      testCompile 'junit:junit:4.12'
      compile 'com.android.support:appcompat-v7:24.1.1'
    }

这个目录下的build.gradle 是开发过程中最重要的,首先看到apply plugin: 'com.android.application',他的作用是把Android插件加入到当前build工程,相应的插件功能可看上一个DSL

android节点则是一些Android的配置,例如app 版本,编译sdk,包名,混淆配置,多渠道等。

dependencies节点是帮助我们添加项目依赖,并且通过上一个.gradle知道默认仓库是jcenter

1.2 配置SDK版本以及其他

问题

你想要设置最低和目标Android SDK版本或者是否混淆等。

解决方法

修改当前build.gradle中android节点中的配置。

分析

android节点是配置app相关的属性。

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
            defaultConfig {
                applicationId "com.kousenit.myandroidapp"
                minSdkVersion 19
                targetSdkVersion 23
                versionCode 1
                versionName "1.0"
            }
        compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    }

这些参数大多在AndroidManifest.xml遗弃,现在在build.gradle中使用。

Configure_SDK_Versions_1.png
Configure_SDK_Versions_1.png
Configure_SDK_Versions_2.png
Configure_SDK_Versions_2.png

1.3 在控制台执行gradle build

问题

你想通过命令run gradle tasks.

解决方法

在控制台运行它。

分析

你不需要为了build Android project 而去下载安装gradle ,因为项目中已经配置好了。直接在Android Studio的terminal中执行。

terminal-build
terminal-build

windows下输入gradlew build即可。

在控制台你可以运行任何gradle支持的task,包含自定义的task,输入gradlew tasks会列出项目中所有 task。这份报告显示项目中所有的默认 task 以及每个 task 的描述。

额外的功能和控制台标记

  • 使用空格分开使一次run多个task。如:

      >gradlew lint hello
    

    lint是自带的,hello是我自己写的,这样就会执行lint后再执行hello.

    gradlew-multiple-tasks
    gradlew-multiple-tasks

    同时你会发现相同名字的task在一次执行中只会执行一遍

  • 使用-x标记排除task

      >gradlew lint -x hello
    

    这一次执行只会执行lint而不会执行hello。

  • 发生故障时继续构建 --continue

    默认情况下,只要任何 task 失败,Gradle 将中止执行。这使得构建更快地完成,但隐藏了其他可能发生的故障。为了发现在一个单一的构建中多个可能发生故障的地方,你可以使用 --continue 选项。

  • 任务名称缩写

    例如我创建一个名为greet的task,在控制台输入>gradlew g也可以执行,也就当你试图执行某个 task 的时候,无需输入 task 的全名.只需提供足够的可以唯一区分出该 task 的字符即可

  • 选择要执行的构建

    调用 gradle 命令时,默认情况下总是会在当前目录下寻找构建文件(译者注:首先会寻找当前目录下的 build.gradle 文件,以及根据settings.gradle 中的配置寻找子项目的 build.gradle )。 可以使用 -b 参数选择其他的构建文件,并且当你使用此参数时 settings.gradle 将不会被使用,看下面的例子:

      app/demo.gradle
    
          task demohello <<{
    
          println "hello demo gradle"
      }
    

    在app目录下我又创建了一个demo.gradle,如果想要执行demo.gradle中的task可以使用-b,如:

      gradlew -b app/demo.gradle demohello
    

    如果不想使用-b 可以使用applydemo.gradle加入到当前build.gradle

      apply plugin: 'com.android.application'
         apply from: 'demo.gradle'
    

    如果这样配置后执行是直接使用task名。

  • 显示 task 使用细节

    执行 gradle help --task someTask 可以获取到 task 的详细信息, 或者多项目构建中相同 task 名称的所有 task 的信息,如下

      Detailed task information for demohello
                               
      Path                 
           :app:demohello  
                               
      Type                 
           Task (org.gradle.api.Task)
                               
      Description          
           -               
                               
      Group                
           -               
                               
      BUILD SUCCESSFUL
    

1.4 使用Android Studio执行Gradle Builds

问题

直接通过Android Studio 执行Gradle

解决方法

使用Gradle 视图去执行tasks

分析

Android Studio 本身是带有Gradle 视图列出所有tasks.

Android Studio gradle view
Android Studio gradle view

选择一个执行,双击或右键选择执行

Android Studio gradle view-run
Android Studio gradle view-run

1.5 添加java library

问题

添加java library 到项目中

解决方法

build.gradledependencies添加

分析

默认的dependencies

    dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      testCompile 'junit:junit:4.12'
      compile 'com.android.support:appcompat-v7:24.1.1'
    }
  • dependencies基本语法

    library依赖完全的语法是 group:name:version

    • 完全语法:

      testCompile group: 'junit', name: 'junit', version: '4.12'

    • 简写语法:

      testCompile 'junit:junit:4.12'

    • 版本为变量的写法(不推荐):

      testCompile 'junit:junit:4.+'

      只要版本大于等于4.0的都可以。

    • jar包依赖:

      dependencies {
      compile files('libs/a.jar', 'libs/b.jar')
      compile fileTree(dir: 'libs', include: '*.jar')
      }

Synchronizing the project

每次更改.gradle后需要同步整个项目,通常IDE会在顶部提示:

sync_now_1
sync_now_1

sync_now_2
sync_now_2

同步时会到仓库去下载依赖包。

Transitive dependencies

间接依赖是指在依赖的A中同时A又依赖了B,那么依赖就会同时下载A,B到项目中,而如果在你的项目中你本身就依赖了B则会出现jar包冲突
可在控制台执行androidDependenciestask查看间接依赖。

间接依赖默认是允许的,可以通过transitive关闭,例如:

    dependencies {
    runtime group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.0.1',
    transitive: false
    }

或,只需要groovy-all本身的jar包,不需要间接依赖的。

    dependencies {
        compile 'org.codehaus.groovy:groovy-all:2.4.4@jar'
    }

    dependencies {
        compile group: 'org.codehaus.groovy', name: 'groovy-all',
           version: '2.4.4', ext: 'jar'
    }

如果是aar则把@jar换成@aar。

Excluding dependencies

如果一个library中有我们不需要的包,则可以通过exclude移除。

    androidTestCompile('com.android.support:appcompat-v7:24.1.1') {
    exclude group: 'support-vector-drawable'
    exclude group: 'animated-vector-drawable'
    }

1.6 通过Android Studio 添加依赖包

问题

使用Android Studio添加依赖,而不是直接使用build.gradle

解决方案

在项目设置中的Dependencies选择依赖lib

分析

打开项目设置,选择Dependencies

dependencies_1
dependencies_1

同时Dependencies提供了6中依赖作用范围:

  • Compile

    compile是对所有的build type以及favlors都会参与编译并且打包到最终的apk文件中。

  • Provided

    Provided是对所有的build type以及favlors只在编译时使用,类似eclipse中的external-libs,只参与编译,不打包到最终apk。

  • APK

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

  • Test compile

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

  • Debug compile

    Debug compile 仅仅针对debug模式的编译和最终的debug apk打包。

  • Release compile

    Release compile 仅仅针对Release 模式的编译和最终的Release apk打包。

依赖的方式有三种,仓库依赖,文件依赖,module依赖。

dependencies_2
dependencies_2

1.7 Configuring Repositories

问题

你想要gradle 准确的实现任何library依赖。

解决方法

配置repositories节点

分析

  • Declaring Repositories

    repositories中告诉gradle到哪里去找到依赖,通常我们都是使用jcenter()

      repositories {
          jcenter()
      }
    

    jcenter 仓库在https://jcenter.bintray.com/

    同时我们也可以使用maven 地址:http://repo1.maven.org/maven2

      repositories {
          mavenLocal()
          mavenCentral()
      }
    

    maven 支持在本地发布仓库,然后使用。

    maven 也能通过url加载依赖。

      repositories {
      maven {
          url 'http://repo.spring.io/milestone'
      }
      }
    

    如果仓库有保护,可以使用username,password

      repositories {
      maven {
          credentials {
              username 'username'
              password 'password'
          }
          url 'http://repo.mycompany.com/maven2'
          }
      }
    

    使用lvy 仓库

      repositories {
          ivy {
              url 'http://my.ivy.repo'
          }
      }
    

    使用本地目录作为仓库

      repositories {
          flatDir {
      dirs 'lib' }
      }
    

第二章:从创建项目到发布

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

推荐阅读更多精彩内容