最新消息:

Gradle for android 学习笔记(二)

android 大步 1012浏览 0评论
本文主要内容:
  1. 理解gradle文件
  2. 开始写构建任务
  3. 自定义构建

理解gradle文件

当我们使用android studio新建一个项目的时候,会自动产生三个gradle的文件,在项目的根目录得到build.gradle和settings.gradle,在app目录下的build.gradle。其目录结构如下:
MyApp
├── build.gradle
├── settings.gradle
└── app
    └── build.gradle
这三个文件有各自的功能。
settings.gradle
对于刚新建的项目,settings.gradle一般只包含:
include ':app'
settings.gradle在初始化的时候被执行,用来定义哪些module应该被构建。在上面的例子中,就只有app这个module被构建。单个的module项目可以不需要settings.gradle。但是如果是多个module项目,则必须有这个文件,否则,gradle不知道应该包含哪些模块。比如我么手动添加依赖库的时候,就需要在settings.gradle中添加依赖模块。
gradle会为每个setttings文件创建一个Settings对象,并从这个对象中调用需要的方法。你不需要知道Settings类的详细信息,但是了解也没坏处,更多Settings类的详细解释,见官方(https://gradle.org/docs/current/dsl/org.
gradle.api.initialization.Settings.html)

项目根目录下的build.gradle文件

如果我们对根目录下的build.gradle文件进行配置,它会应用到项目内的所有的module。它默认包含两个块:
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}
allprojects {
    repositories {
        jcenter()
    }
}
buildscript块:实际的用来配置构建的。
repositories块用来指定仓库,这里使用jcenter。gradle可以从JCenter下载我们需要的依赖库。
dependencies块:用来配置构建所需要的依赖,是构建。默认只会定义一个依赖,即google为gradle所编写的android插件。所有的模块都需要这个插件,因为有了这个插件之后,才能执行android相关的任务。(注意:不要与把项目所依赖的那些库弄混,这里不能放项目依赖的库,比如什么support v7,jar之类的。)
allprojects块:对项目所有的module定义一些属性。你可以在其内部进行扩展,添加任务。这些任务在所有module中都是可用的。

app目录下的build.gradle文件

该文件包含的参数,只会作用于android app模块。它也可以重写任何项目根目录下的build.gradle文件的参数。内容如下:
apply plugin: 'com.android.application'
android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"
    defaultConfig {
        applicationId "com.gradleforandroid.gettingstarted"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile
             ('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}

Plugin

第一行指定android应用插件,该插件在根目录下的build.gradle进行了配,即com.android.tools.build:gradle:x.x.x 。这个插件有谷歌的团队开发和维护的,并且提供了构建、测试和打包应用和库 所需要的全部任务。

Android

这个块包含了前面提到的android插件的全部android特定的配置。
必须包含属性有compileSdkVersion和buildToolsVersion:
compileSdkVersion:用于指定编译app的android sdk版本
buildToolsVersion:用来指定构建工具的版本
构建工具包含了命令行工具,如aapt、zipalign、dx和renderscript。用于生成应用内部的所有组成文件。我们可以使用sdk manager下载构建工具。
defacultConfig块:用来配置app的核心属性。在这个块中,将AndroidManifest.xml中所有对应的属性覆盖:
defaultConfig {
    applicationId "com.gradleforandroid.gettingstarted"
    minSdkVersion 14
    targetSdkVersion 22
    versionCode 1
    versionName "1.0"
}
applicationId:这个是覆盖AndroidManifest文件中的包名。但是,applicationId和包名之间有一些区别。在Gradle之前的编译系统里,AndroidManifest.xml中的包名有两个作用,一个是用来作为app的唯一标识,另一个功能是作为R资源类(R文件)的名字。而Gradle通过applicationId这个属性,使用build variant ,可以方便的创建多个不同的app版本。比如:我可以在不修改代码的前提下,同时编译两个版本,同时创建app的免费版和付费版,可以同时安装到一部手机上。 而仅仅只需要指定两个不同的applicationId即可。
minSdkVersion:app支持的最低的android sdk版本
targetSdkVersion :app面向的android sdk版本。
versionCode :版本号,只能是整数
versionName :版本名,是字符串。一般我们使用这个来标志app的具体版本,使用x.y.z的方式来标明。
因为我们在build.gradle声明了这些属性,所以,我们在AndroidManifest文件中我们可以不用再写这些属性了。
buildTypes块:用来定义如何构建和打包app的不同构建类型。后面会详细讲解构建类型(build type)。
Dependencies块:这个块是Gradle配置的标准的一部分,所以需要放到android块外面。该块用来定义app或者库项目所有的依赖。默认,一个新的android app所有的jar文件依赖全都在libs目录。

开始任务

我们可以通过执行:
$ gradlew tasks
来查看所有的任务。
$gradlew tasks --all
查看每个任务的依赖。
我们也可以预览任务所需要执行的步骤,但这些步骤实际上是不会真的执行的:
$gradlew tasks -m
$gradlew tasks -dry-run

基本任务

gradle的android插件利用了java基础插件。添加了一些标准的生命周期任务和常见的属性。基础插件定义了assemble和clean任务,java基础插件定义了check和build任务。这些定义了下面的任务:
assemble:整合项目的输出
clean:清空项目的输出
check:运行所有检查,常用语单元测试和片段测试(instrumentation test)
build:运行assemble和check
java基础插件添加了源集的概念。android插件添加了许多android特有的任务。

Android任务

android插件扩展了基本任务。下面是在android环境执行的任务:
assemble:为每个构建类型创建apk文件
clean:删除所有build目录下的文件
check:之家Lint检查,并且能在检查到的Lint问题的时候退出构建
build:同时运行assemble和check
默认assemble任务依赖于assembleDebug和assembleRelease。如果添加更多的构建类型,则依赖也会更多。
android还会添加下面的任务:
connectedCheck:连接设备或模拟器来运行测试
deviceCheck:为其他插件提供占位任务,用来在远程设备上运行测试
installDebug 和installRelease:安装特定的app版本到设备或模拟器上
所有的install任务同时也伴随uninstall任务。
build任务依赖于check任务,而不依赖connectedCheck或deviceCheck。这样确保常规检查不需要连接设备或运行模拟器。运行check任务会/生一个Lint报告,包含所有的警告和错误。在目录 app/build/outputs/lint-results.html , 如下:
4(WS6FU(`2{CF`5T}$EVTE9.png
当你构建一个app的时候,Lint会检查所有可能导致app奔溃的问题,并且当找到任意的问题后,都会自动退出构建并在命令行中打印这些错误。文件路径: app/build/outputs/lint-results-release-fatal.html。

设置Android Studio的终端

我们可以不用windows系统自带的终端,而使用如git shell等终端。依次打开 File——Settings——Terminal,然后设定为git shell路径即可。

自定义构建

当我们修改build.gradle文件后,android studio会自动提示我们去Sync now文件。当然也可以手动点击Tools——Android——Sync Project with Gradle Files  或者直接点击工具栏的图标:
{0)V2Z[B}(@8GB)J@5WFT2D.png
然后android studio实际会执行generateDebugSources任务会根据build.gradle去生成所需的class文件。
操作manifest项目
build.gradle还可以配置下面的属性:
testApplicationId:这个应用ID用于片段测试APK
testInstrumentationRunner : 运行测试的单元测试运行器( the JUnit test runner )的名字
signingConfig:见后面的文章
proguardFile和proguardFiles:指定混淆规则

Android Studio内配置构建参数

我们可以使用android studio内置的功能来修改构建参数,注意,我们界面修改的参数,等同于修改build.gradle文件
右键选择项目——Open Module Setting就会参数“Project  Structure”窗口。
[RMY~Y4E2T`{@21%2`WAQDO.png

BuildConfig和资源(resource)

从sdk版本17开始,构建工具会产生一个叫做BuildConfig的类,包含了DEBUG常量,可以根据构建类型来进行设定。这个很有用,例如,我们只想在调试的时候打印Log。我们可以通过Gradle去扩展这个文件,使用一个常量在debug版本或正式版中包含不同的值。或者,我们可以设置服务器地址的指向,在内网测试的时候将服务器指向内网,而发布的正式版,指向外网,如下:
android {
    buildTypes {
        debug {
            buildConfigField "String", "API_URL",
              "\"http://test.example.com/api\""
            buildConfigField "boolean", "LOG_HTTP_CALLS", "true"
        }
        release {
            buildConfigField "String", "API_URL",
              "\"http://example.com/api\""
            buildConfigField "boolean", "LOG_HTTP_CALLS", "false"
        }
    }
}
大家可以看到,上面的服务器地址被双引号包裹,而这个双引号必须进行转义,这样才能得到一个实际的字符串。然后添加buildConfigField行,这样我们就可以直接在java代码中使用BuildConfig.API_URL 和  BuildConfig.LOG_HTTP ,实现切换服务器和关闭开启打印日志功能。
最近,android工具开发小组还用同样的方式来配置资源:
android {
    buildTypes {
        debug {
            resValue "string", "app_name", "Example DEBUG"
        }
        release {
            resValue "string", "app_name", "Example"
        }
    }
}
上面的双引号不是必须的,因为默认情况下资源的值设定为value=""。

整个项目的设定

如果一个项目中包含多个模块,我们不需要去修改每个app的build.grale文件,而只需要去项目根目录下的build.gradle进行设定即可。我们已经知道如何使用allprojects块 ,来为所有的module定义仓库,同样,我们也可以在allprojects块中指定所有module的compileSdkVersion和buildTooksVersion和使用“com.android.application”插件。如下:
allprojects {
    apply plugin: 'com.android.application'
    android {
        compileSdkVersion 22
        buildToolsVersion "22.0.1"
    }
}
还有一个更好的方法是,在根目录下的build.gradle中定义一个变量,给其赋值。然后再去每个module的build.gradle文件中去添加这个变量,这样,当我们需要修改所有module的一些属性的时候,只需要去根目录的build.gradle文件中修改这个变量值即可。而这需要利用Gradle的一个特性:Gradle允许通过ext块来添加很多附加属性。
例如,我们可以先去项目根目录下build.gradle文件添加:
ext {
    compileSdkVersion = 22
    buildToolsVersion = "22.0.1"
}
然后再去每个module的build.gradle文件中定义:
android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
}

项目属性

常用的定义属性的方式有下面三种:
  • ext块
  • gradle.properties文件
  • 命令行下-P参数
下面是在build.gradle文件中,同时使用这三种方式:
ext {
  local = 'Hello from build.gradle'
}
task printProperties << {
  println local        // Local extra property
  println propertiesFile        // Property from file
  if (project.hasProperty('cmd')) {
    println cmd        // Command line property
  }
}
同时在根目录下的 gradle.properties文件中,添加下面一行:
propertiesFile = Hello from gradle.properties
然后,我们去命令行下运行printProperties任务,输出如下:
$ gradlew printProperties -Pcmd='Hello from the command line'
:printProperties
Hello from build.gradle
Hello from gradle.properties
Hello from the command line
注意:我们可以在根目录下和模块下定义相同的属性,但是模块下build.grale内定义的属性会覆盖跟目下定义的。

默认任务

如果你运行Gradle的时候没有指定任务,那么它会运行help任务,打印一些信息告诉你如何使用Gradle。这是因为help任务设定为默认任务。当然,我们可以用自己的一个或多个任务覆盖这个默认任务。我们可以通过下面的方式去指定默认任务:
defaultTasks 'clean', 'assembleDebug'
这样,当你运行Gradle wrapper而不指定任何参数的时候,就会执行clean和assembleDebug任务。
下面是linux或osx下才能执行grep命令:
$ gradlew tasks | grep "Default tasks"
Default tasks: clean, assembleDebug

 

 

转载请注明:大步's Blog » Gradle for android 学习笔记(二)

SiteMap