Android Gradle 构建入门2-Gradle

Android Gradle 构建入门1-Groovy
Android Gradle 构建入门2-Gradle
demo源码
Gradle文档

Projects 和 tasks

每一个构建都是由一个或多个 projects 构成的. 一个 project 到底代表什么取决于你想用 Gradle 做什么. 举个例子, 一个 project 可以代表一个 JAR 或者一个网页应用. 它也可能代表一个发布的 ZIP 压缩包, 这个 ZIP 可能是由许多其他项目的 JARs 构成的. 但是一个 project 不一定非要代表被构建的某个东西. 它可以代表一件**要做的事, 比如部署你的应用.
不要担心现在看不懂这些说明. Gradle 的合约构建可以让你来具体定义一个 project 到底该做什么

task

task taskName{
    doFirst{
        ....
    }
    doLast{
        ....
    }
}

这样创建一个TaskContainer。可以把它看作一个任务队列,队列中有一个一个的Task。按住control右击鼠标即可查看TaskContainer这个类的方法。doFirst是将该task加入队列的第一个位置。doLast是将该task加入任务队列的尾部。

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"
}

再来看这个应该就很明白了

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    ....
}

android后面的这个闭包到底有什么属性了,control+右击 android就可以看到AppExtension这个类。

我么可以在这个android{ ... } 做一些特别操作吗?

先介绍一个知识点
因为 Android 项目中会有大量相同的 task,并且它们的名字基于 Build TypesProduct Flavor 生成。
为了解决这个问题,**android
** 对象有三个属性:
**applicationVariants
**(只适用于 app plugin)
**libraryVariants
**(只适用于 library plugin)
**testVariants
**(app、library plugin 均适用)

这三个属性会分别返回一个 ApplicationVariant、LibraryVariant和TestVariant对象的 DomainObjectCollection。(点击查看API)
注意,使用这三个 collection 中的其中一个都会触发生成所有对应的 task。这意味着使用 collection 之后不需要重新配置。
DomainObjectCollection 可以直接访问所有对象,或者通过过滤器进行筛选。

//each 是Groovy的遍历集合的操作
android.applicationVariants.each { variant ->
    ....
}
//或者 all是DomainObjectCollection提供的遍历操作
android.applicationVariants.all { variant ->
    ....
}

这个是遍历集合将每一个元素得到一个ApplicationVariant对象
applicationVariants是一个强大的对象,可以让我们做很多特别的事情。
如何可以看源代码的话可以看到

public DomainObjectSet<ApplicationVariant> getApplicationVariants()

applicationVariants的详细属性参考或者查看com.android.build.gradle.api.ApplicationVariant这个类的源代码。这个代码会在你的Gradle包当中。

如果你想修改输出的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直译过来就是产品特色,不是渠道的意思。可以打出不同特的的包。

  • 不同的包名的包
  • 不同的版本号
  • 不同的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可以替换任何地方的值

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,302评论 25 707
  • Gradle是什么? Android Studio 基于 Gradle 构建系统,并通过 Android Grad...
    CP9阅读 1,246评论 0 3
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,437评论 2 45
  • 发表感想阅读 176评论 0 0
  • 我已经大学毕业后踏入社会已经两年了,昨天去参加一个闺蜜的毕业典礼。由于她太忙了,我们几个高中的同学都被搁置在一个大...
    梦清许阅读 304评论 3 2