Android Gradle 構(gòu)建入門2-Gradle

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容