配置Gradle构建
配置Gradle构建
这篇文章建立在 “构建系统概述” 和 “构建和运行Android Studio”之上,向你展示如何在product flavors和build types基础上使用build variants。
构建基础配置
Android Studio包含一个顶级的构建文件和每个模块的构建文件。构建文件被称为 build.gradle,它是一个纯文本文件,它使用Groovy语法来配置由Android Gradle插件提供的元素。在大多数情况下,你只需要编辑模块级别的构建文件。例如,BuildSystemExample项目的app模块的构建文件是像这样的:
apply plugin:'com.android.application' |
apply plugin:'com.android.application' 是应用Android Gradle插件来构建。这样添加Android特定的构建任务到顶级构建任务中,并且使用 android{…}中的元素来指定Android特定的构建项。
android{….} 配置所有的Android特定构建项:
compileSdkVersion 项指定编译的目标。
buildToolsVersion 项指定使用什么版本的构建工具。使用SDK管理器来安装多个版本的构建工具。
注意:请始终使用其主要版本号高于或等于您的编译目标SDK的版本。
defaultConfig 元素动态的配置在AndroidManifest.xml中的设置。在defaultConfig的值将覆盖manifest文件中的值。配置在defaultConfig的值将应用于所有的构建变种(build variants),除非构建变种的配置覆盖了这些值。
buildType元素控制如何构建和打包你的应用。默认的构建系统定义了两个构建类型:debug和release。debug构建类型包含debugging符号,并且使用了debug key签名。release构建类型默认没有被签名。在这个例子中构建文件配置了release版本,使用了ProGuard。
dependencies元素是在android元素外面的,并且在android元素后面。这个元素声明了这个模块的依赖。在一下的章节中都有依赖的内容。
注:当你在你的项目中改变了构建文件,Android Studio为了导入改变了构建配置而要求项目同步。点击黄色通知栏中的”Sync Now”按钮来同步改变的内容。
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/></v:shapetype><v:shape id="图片_x0020_1" o:spid="_x0000_i1027" type="#_x0000_t75" alt="http://developer.android.com/images/tools/as-gradlesync.png" style='width:415.2pt; height:70.2pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\SUNNYA~1\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png" o:title="as-gradlesync"/></v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
图一. 同步 Android Studio中的项目。
声明依赖
这个例子的应用模块声明了3个依赖:
... dependencies { // Module dependency compile project(":lib") // Remote binary dependency compile 'com.android.support:appcompat-v7:19.0.1' // Local binary dependency compile fileTree(dir:'libs', include:['*.jar']) } |
每个依赖在下面给出描述。构建系统添加所有类型为”compile”的依赖到编译路径中,并且最终将他们打到最终的包中。
Module dependencies
app模块依赖于lib模块。因为像在”Open an Activity from a Library Module”中描述的,MainActivity登录LibActivity1.
compile project(":lib") 声明了依赖lib模块。当你构建app模块的时候,构建系统将会集合lib模块。
运程二进制依赖
app和lib模块都使用了来自Android支持库的ActionBarActivity类,所有这些模块都依赖它。
compile 'com.android.support:appcompat-v7:19.0.1' 通过指定Maven坐标来声明了对Android支持库19.0.1版本的依赖。在Android SDK的仓库包中Android的支持库是可用的。如果你安装的SDK没有这个包,通过使用SDK管理工具下载安装它。
Android Studio默认使用了Maven的中央仓库来配置项目。(这个配置在项目的顶级构建文件中)。
本地二进制依赖
一些模块不使用任何的本地系统二进制依赖。如果你有依赖本地二进制依赖的模块,拷贝JAR文件到<moduleName>/libs目录下。
compile fileTree(dir: 'libs', include: ['*.jar']) 告诉构建系统将 app/libs目录下面的JAR文件依赖包含到编译路径,并且最终在最终的包中。
有关在Gradle更多的依赖信息,请查看Gradle的用户指南(Dependency Management Basics )。
运行ProGuard
构建系统运行ProGuard,以达到在构建过程中混淆你的代码的目的。在BuildSystemExample中,为了release构建运行ProGuard修改app模块的构建文件:
... android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro' } } } ... |
getDefaultProguardFile('proguard-android.txt') 从安装的Android SDK中获取默认的ProGuard设置。你可自定义ProGuard规则,Android Studio 将会加模块根部的proguard-rules.pro文件添加到模块特定的规则中。
包的标识:Application ID
在Android构建系统中,applicationId属性是唯一标示发行应用包。Application ID在build.gradle文件的android节点中设置。
apply plugin:'com.android.application' android { compileSdkVersion 19 buildToolsVersion "19.1" defaultConfig { applicationId "com.example.my.app" minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" } |
注: applicationID只能在build.gradle文件中被指定,不能再AndroidManifest.xml文件中。
当使用build variants,构建系统可以让你为每个product flavors和build types指定包的唯一标示。在build type中的Application ID被添加到product flavors作为后缀。
productFlavors { pro { applicationId ="com.example.my.pkg.pro" } free { applicationId ="com.example.my.pkg.free" } } buildTypes { debug { applicationIdSuffix ".debug" } } .... |
包名依然需要在manifest文件中指定。它在你的源码中用来涉及你的R class和解决相关activity/service注册问题。
package="com.example.app"> |
注:如果你有多个manifests(比如,一个product flavor指定的manifest和一个build type的manifest),包名在这些manifests中是可选的。如果它再这些manifests中被指定,那报名必须和src/main目录下的manifest的包名一致。
有关更多的关于构建文件和构建过程信息,请看 Build System Overview。
配置签名设置
debug和release版本的app在是否能在安全设备调试和如何进行签名是有区别的。构建系统使用一个默认的key来签名debug版本,并且为了在构建过程中不出现密码提示,使用了已知的证书。构建系统不会签名release版本,除非你明确定义了签名配置。如果你没有一个release的key,你可以安装”Signing your Applications”中描述的进行生成。
使用build variants工作
这个章节描述构建系统如何帮助你在一个项目中的同一个应用创建不同的版本。当时有一个demo和paid版本的时候,这是有用的,或者是你想在Google Play上为不同配置的设备发布多个APK。
构建系统使用 product flavors为你的应用创建不同的版本。每个版本有可能有不同的特性和设备要求。构建系统也应用 build types到不同的构建中,并且打包配置到每个版本中。 每个product flavor和build type的组合形成了一个build variant。构建系统为每个build variant生成了不同的APK。
Build variants
这个项目例子包含了两个默认的build types(debug 和release),还有两个product flavors(demo和full)。更多关于使用build variants的高级信息,查看”Build System Overview”。
Product flavors
为你的应用创建不同的版本:
<!--[if !supportLists]-->1、<!--[endif]-->在构建文件中定义product flavors
<!--[if !supportLists]-->2、<!--[endif]-->为每个flavor创建附加的源码路径
<!--[if !supportLists]-->3、<!--[endif]-->添加flavor特定的源码到你的项目中
接下来的章节带你了解 BuildSystemExample项目中的每个细节。在BuildSystemExample应用中创建两个Flavor。一个demo flavor和一个full flavor。两个flavors共享 MainActivity,MainActivity中有一个按钮跳转到一个新的activity—SecondActivity.对于两个flavor来说SecondActivity是不同的,因此你应该模拟这样的情况:full flavor中的Activity的特性要比demo flavor中的Activity多。在练习的最后,你将得到不同flavor的不同APK。
在构建文件中定义product flavors
为app模块中的构建文件定义两个product flavors:
... android { ... defaultConfig {...} signingConfigs {...} buildTypes {...} productFlavors { demo { applicationId "com.buildsystemexample.app.demo" versionName "1.0-demo" } full { applicationId "com.buildsystemexample.app.full" versionName "1.0-full" } } } ... |
这个项目的flavor定义支持使用defualtConfig相同的配置。所有flavors相同都配置都定义在defaultConfig中,每个flavor可以覆盖任何默认的值。上面的构建文件使用了 applicationId属性来分配给每个flavor:自从每个flavor创建了不同的app,他们应该需要不同的包名。
注:在Google Play中,为使你的应用可以拥有多APK支持。给你的所用variants分配相同的包名,并且给每个viant不同的versionCode. 为了再Google Play中区分不同的variants,你应该分配不同的包名给每个variant。
为每个flavor添加额外的源码目录
现在你应该创建源码目录,并且将SecondActivity添加到不同的flavor中。为demo flavor创建源码目录结构:
<!--[if !supportLists]-->1、<!--[endif]-->在Project模板中,展开BuildSystemExample,并且展开app目录
<!--[if !supportLists]-->2、<!--[endif]-->右键src目录,选择New>Directory
<!--[if !supportLists]-->3、<!--[endif]-->使用”demo”作为目录的名字
<!--[if !supportLists]-->4、<!--[endif]-->同样的创建如下目录:
app/src/demo/java
app/src/demo/res
app/src/demo/res/layout
app/src/demo/res/values
目录的结构看起来像图1:
<!--[if gte vml 1]><v:shape id="图片_x0020_2" o:spid="_x0000_i1026" type="#_x0000_t75" alt="http://developer.android.com/images/tools/as-demoflavordirs.png" style='width:150pt;height:162.6pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\SUNNYA~1\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png" o:title="as-demoflavordirs"/></v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
图一:demo flavor的目录
添加不同的activity到不同的flavor中:
添加SecondActivity到demo flavor中:
<!--[if !supportLists]-->1、<!--[endif]-->在Project模板中,右键app模块,选择New>Activity。
<!--[if !supportLists]-->2、<!--[endif]-->选择 Blank Activity,点击Next
<!--[if !supportLists]-->3、<!--[endif]-->输入activity名字: SecondActivity
<!--[if !supportLists]-->4、<!--[endif]-->输入包名”com.buildsystemexample.app”
<!--[if !supportLists]-->5、<!--[endif]-->在app/src/demo目录中右键java目录选择New>Package。
<!--[if !supportLists]-->6、<!--[endif]-->输入com.buildsystemexample.xapp
<!--[if !supportLists]-->7、<!--[endif]-->将SecondActivity拖拽到app/src/demo/java中
<!--[if !supportLists]-->8、<!--[endif]-->接受默认的Refactor
为demo flavor添加SecondActivity的布局文件和资源文件
<!--[if !supportLists]-->1、<!--[endif]-->从ap/src/main/res/layout中将activity_second.xml文件拖拽到app/src/demo/res/layout中
<!--[if !supportLists]-->2、<!--[endif]-->接受默认的提示
<!--[if !supportLists]-->3、<!--[endif]-->将strings.xml从app/src/main/res中拷贝到app/src/demo/res中
<!--[if !supportLists]-->4、<!--[endif]-->替换string.xml文件中的内容,如下:
<!--[if !supportLists]-->5、<!--[endif]--><?xml version="1.0" encoding="utf-8"?> <resources> <stringname="hello_world">This is the full version!</string> </resources> |
注:从现在开始,你可以为每个flavor单独开发SecondActivity. 比如,你可以为full flavor的activity添加更多的属性。
为了让指定的flavor文件工作,点击IDE窗口邮编的Build Variants,并且选择你想使用的flavor,就像图2. Android Studio可能会展示其他flavor的错误,但是这并不影响输出内容的构建。
<!--[if gte vml 1]><v:shape id="图片_x0020_3" o:spid="_x0000_i1025" type="#_x0000_t75" alt="http://developer.android.com/images/tools/as-buildvariants.png" style='width:210pt;height:113.4pt;visibility:visible;mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\SUNNYA~1\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png" o:title="as-buildvariants"/></v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
图2
从MainActivity登入到指定flavor的activity
SecondActivity在所有的flavors中都有相同的包名,你可以同main activity中登入。编辑mainActivity:
<!--[if !supportLists]-->1、<!--[endif]-->编辑 activity_main.xml,添加一个按钮:
<LinearLayout ...> ... <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button2" android:onClick="onButton2Clicked"/> </LinearLayout> |
<!--[if !supportLists]-->2、<!--[endif]-->为按钮添加text标题,和按钮事件onButton2Clicked
<!--[if !supportLists]-->3、<!--[endif]-->在MainActivity中添加如下代码:
publicvoid onButton2Clicked(View view){ Intent intent =newIntent(this,SecondActivity.class); startActivity(intent); } |
<!--[if !supportLists]-->4、<!--[endif]-->编辑manifest文件
<manifest ...> <application ...> ... <activity android:name="com.buildsystemexample.app.SecondActivity" android:label="@string/title_activity_second"> </activity> </application> </manifest>
|
Build types
Build types表现为为每个app包构建包版本。默认的debug和release被提供:
... android { ... defaultConfig {...} signingConfigs {...} buildTypes {...} productFlavors {...} buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro' } debug { debuggable true } } } ... |
注:尽管在build.gradle文件中默认只有release构建类型,当时release和debug构建类型都被应用的每个构建中。
在这个例子中,product flavors和build types创建了一下的build variants:
demoDebug
demoRelease
fullDebug
fullRelease
为这个例子构建,可以点击Android Studio的Build菜单,或者在命令行中执行 assemble命令。
注:Build>Make Project会编译项目中所有的源码。Build>Rebuild Project选项重新编译所有的源码。
会为不同的build variant创建不同的输出目录。