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可以替换任何地方的值

    原文作者:shawn_yy
    原文地址: https://www.jianshu.com/p/6230c7ca2bcf
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞