Android Gradle 構(gòu)建入門1-Groovy
Android Gradle 構(gòu)建入門2-Gradle
demo源碼
Gradle文檔
Projects 和 tasks
每一個構(gòu)建都是由一個或多個 projects 構(gòu)成的. 一個 project 到底代表什么取決于你想用 Gradle 做什么. 舉個例子, 一個 project 可以代表一個 JAR 或者一個網(wǎng)頁應(yīng)用. 它也可能代表一個發(fā)布的 ZIP 壓縮包, 這個 ZIP 可能是由許多其他項目的 JARs 構(gòu)成的. 但是一個 project 不一定非要代表被構(gòu)建的某個東西. 它可以代表一件**要做的事, 比如部署你的應(yīng)用.
不要擔(dān)心現(xiàn)在看不懂這些說明. Gradle 的合約構(gòu)建可以讓你來具體定義一個 project 到底該做什么
task
task taskName{
doFirst{
....
}
doLast{
....
}
}
這樣創(chuàng)建一個TaskContainer??梢园阉醋饕粋€任務(wù)隊列,隊列中有一個一個的Task。按住control右擊鼠標(biāo)即可查看TaskContainer這個類的方法。doFirst是將該task加入隊列的第一個位置。doLast是將該task加入任務(wù)隊列的尾部。
apply plugin: 'com.android.application' 是什么鬼?
這個舉個例子
apply plugin: MyPlugin
myAndroid{
version = 1001
name = "hi android"
}
class MyPlugin implements Plugin<Project>{
@Override
void apply(Project target) {
target.extensions.create("myAndroid", MyAndroid)
target.task('myassemable') {
doLast{
// do other thing
println "Version is " + project.myAndroid.version
println "name is " + project.myAndroid.name
}
}
}
}
class MyAndroid{
def version = 100
def name = "Android"
}
再來看這個應(yīng)該就很明白了
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
....
}
android后面的這個閉包到底有什么屬性了,control+右擊 android就可以看到AppExtension這個類。
我么可以在這個android{ ... } 做一些特別操作嗎?
先介紹一個知識點
因為 Android 項目中會有大量相同的 task,并且它們的名字基于 Build Types 和 Product Flavor 生成。
為了解決這個問題,**android
** 對象有三個屬性:
**applicationVariants
**(只適用于 app plugin)
**libraryVariants
**(只適用于 library plugin)
**testVariants
**(app、library plugin 均適用)
這三個屬性會分別返回一個 ApplicationVariant、LibraryVariant和TestVariant對象的 DomainObjectCollection。(點擊查看API)
注意,使用這三個 collection 中的其中一個都會觸發(fā)生成所有對應(yīng)的 task。這意味著使用 collection 之后不需要重新配置。
DomainObjectCollection 可以直接訪問所有對象,或者通過過濾器進(jìn)行篩選。
//each 是Groovy的遍歷集合的操作
android.applicationVariants.each { variant ->
....
}
//或者 all是DomainObjectCollection提供的遍歷操作
android.applicationVariants.all { variant ->
....
}
這個是遍歷集合將每一個元素得到一個ApplicationVariant對象
applicationVariants是一個強大的對象,可以讓我們做很多特別的事情。
如何可以看源代碼的話可以看到
public DomainObjectSet<ApplicationVariant> getApplicationVariants()
applicationVariants的詳細(xì)屬性參考或者查看com.android.build.gradle.api.ApplicationVariant這個類的源代碼。這個代碼會在你的Gradle包當(dāng)中。
如果你想修改輸出的APK包名或者想自己修改Manifest的配置文件
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{}
mytest{}
}
applicationVariants.all{ variant->
println "variant----variant.buildType.name ="+variant.buildType.name +
"\nvariant.name=" + variant.name+
"\nvariant.baseName=" + variant.baseName
def ofs = variant.outputs
println "**********************************************************************"
ofs.each {o ->
println "o----name = "+o.name +
" \nbaseName="+o.baseName +
" \noutfile = "+o.outputFile +
" \nprocessManifest="+o.processManifest
//改manifest
o.processManifest.doLast {
//do things
}
//改名字
def file = o.outputFile;
def fileName = "myApk.apk"
o.outputFile = new File(file.parent, fileName)
//等等
println "------end------"
}
}
打印的日志:
variant----variant.buildType.name =mytest
variant.name=mytest
variant.baseName=mytest
**********************************************************************
o----name = mytest
baseName=mytest
outfile = /Users/study/Discipline/gradlesimple/build/outputs/apk/gradlesimple-mytest-unsigned.apk
processManifest=task ':gradlesimple:processMytestManifest'
------end------
variant----variant.buildType.name =debug
variant.name=debug
variant.baseName=debug
**********************************************************************
o----name = debug
baseName=debug
outfile = /Users/study/Discipline/gradlesimple/build/outputs/apk/gradlesimple-debug.apk
processManifest=task ':gradlesimple:processDebugManifest'
------end------
variant----variant.buildType.name =release
variant.name=release
variant.baseName=release
**********************************************************************
o----name = release
baseName=release
outfile = /Users/study/Discipline/gradlesimple/build/outputs/apk/gradlesimple-release-unsigned.apk
processManifest=task ':gradlesimple:processReleaseManifest'
------end------
個性化定制APK
android {
....
productFlavors {
flavor1 {
packageName "com.cyy.flavor1"
versionCode 20
//manifestPlaceholders = ["place":"value" , "place1":"value1"]
....
}
flavor2 {
packageName "com.cyy.flavor2"
versionCode 18
.....
}
}
}
productFlavors直譯過來就是產(chǎn)品特色,不是渠道的意思??梢源虺霾煌氐牡陌?。
- 不同的包名的包
- 不同的版本號
- 不同的ICON 或者其他的資源圖片
- 不同的Manifest文件的包
....
主要說一下不同的Manifest文件的包,渠道包只是其中的一種
例如,我們App想打兩個包,一個是桌面程序,一個就是普通程序,我們都知道App要是桌面的話需要在Manifest文件中注冊
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
但是這樣的話就打出的包都是桌面的,這時productFlavors排上用途了,
先寫上占位符
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.${MYHOME}" />
<category android:name="android.intent.category.${MYDEFAULT}" />
然后在productFlavors替換掉就行了
flavor1 {
manifestPlaceholders = ["MYHOME":"HOME" , "MYDEFAULT":"DEFAULT"]
}
flavor2{
manifestPlaceholders = ["MYHOME":"MYHOME" , "MYDEFAULT":"MYDEFAULT"]
}
manifestPlaceholders可以替換任何地方的值