Android之通過配置Flavor實現一個項目打包成多個apk


最近我老大問我一個問題,說Android可不可以像iOS那樣,通過target對項目進行管理啊。老大提這個問題也是正常的,我公司的主要是幫別的公司做硬件定制的,每定制一個硬件就要定制一個APP,但是很多APP的定制其實都是基於同一個APP,只是改改圖標,改改部分功能,但是就是這么簡單的改變都需要新建一個項目,試想想如果有幾十個項目,剛好修復了一個bug,那么要把這個修復同步到所有項目中,那同步代碼的工作量是多么的大,而且還不能保證同步不出錯。所以老大讓我找找有沒有方法可以像iOS的target那樣處理。

這里需要先理解iOS的target是什么。知道的同學可以自行忽略這段。iOS中project包含資源、文件、信息等等,而這些就像一些積木,而target則作為標志,通過不同的標志進行組合,這里有官方的介紹,英語好的同學可以自己去看看。這樣組合的好處就是,如果一個項目只需要改變一下圖標,那只需要增加圖標的資源,然后再增加標志,那就可以生成一個新的APP。抱着試試的心態去尋找Android的target,但是Android並沒有這個東西,不過卻找到了另一個東西,那就是配置Flavor。

productFlavors

先來看一段代碼

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.z.q.flavor"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    productFlavors{
        flavor1{//自定義flavor1的參數
            applicationId "com.z.q.flavor1"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
        }
        flavor2{//在defaultConfig的基礎上做修改
            applicationIdSuffix ".flavor2"//輸出:com.z.q.flavor.flavor2
            versionNameSuffix "-flavor2"//輸出:1.0-flavor2
        }
    }
    ...
}

這個是module里面的build.gradle部分代碼,這里面主要增加的productFlavors,這個就是來配置不同項目的參數。在這里我配置了兩個項目,分別是flavor1和flavor2。不同的項目ID當然需要不同,配置ID的方法有兩種: 
1. 第一種就是直接使用applicationId這個屬性,直接給flavor1配置一個ID; 
2. 第二種就是使用applicationIdSuffix這個屬性,這個的意思是在defaultConfig的默認ID基礎上在后面追加一段。

而versionName也是和applicationId一樣有兩種方法。如果沒配置的屬性會默認的使用defaultConfig里面的屬性。到這里不同項目的build.gradle里面的配置大致完成了,如果還想了解更多的配置信息,可以到Google官網了解。

資源文件配置

在build.gradle我配置了兩個項目,那么相應的需要建立兩個資源文件夾。 

在build.gradle我配置了兩個項目,那么相應的需要建立兩個資源文件夾。 
圖片 
這兩個文件名字必須和build.gradle里面配置的兩個Flavors名字相同,現在可以在這兩個文件夾里創建各自項目的資源了。 
在這兩個文件夾里面創建資源的時候一定要和main的文件格式一致,如圖: 
這里寫圖片描述 
這個文件格式一致是指包名必須相同。這時有人可能會問為什么flavor1里面有res資源文件,為什么flavor2里面沒有呢?

我們先從main文件夾來看,在main文件夾里面有Java代碼文件,res資源文件和清單文件。在配置Flavor中,在進行構建的時候會將選中的Flavor和main進行結合構建,說白了就是如果Flavor沒有的東西就會使用main里面的代替。上圖,我就選中了flavor2,具體怎么選着請看下圖。因為flavor2中沒有res資源和清單文件,那么它就會使用main里面的res資源和清單文件;而如果選着flavor1,那么就會使用flavor1中res資源里面的布局文件。在這里可以看到不同項目中的res資源可以有相同的,Android studio在編譯的時候會優先使用Flavor里面的res資源,如果沒有再使用main的res資源。 
這里寫圖片描述 
細心的同學可能會發現Java文件夾里面的代碼文件,為什么兩個Flavor中都有Flavor代碼文件,而main中卻沒有,但是main中有MainActivity代碼文件,而兩個Flavor文件中卻沒有。這是因為在編譯的時候,Flavor的Java的文件不會覆蓋main里面的Java的文件,所以如果Flavor里面有的Java文件,main里面就不能有,如果是所有項目都相同的Java文件,那么就可以放在main文件里。

到目前為止main文件里面,已經把Java代碼文件和res資源文件說明,剩下就只有清單文件了,清單文件比較特殊,需要單獨拿來講解。

清單文件

清單文件不像Java代碼文件那樣每個項目相同的Java代碼文件不可以和main中的Java代碼文件共存,而是main和每個項目都可以有清單文件,但是又不會像res資源文件那樣項目中的res資源文件會覆蓋main的res資源文件。

在編譯的時候Android studio會把main的清單文件和選中項目的清單文件合並,但是合並就會出現沖突。其實谷歌那邊早就想到會有這些問題,所以已經提供了解決的方法了。

在這里我只介紹兩種合並方法:merge和replace

這里寫圖片描述 
這張是main的清單文件

這里寫圖片描述
這是flavor1的清單文件

這里寫圖片描述
這是flavor2的清單文件

在main的清單文件中缺少了主題,而在flavor1清單文件中只有主題沒有其他,那么在這里使用merge就會把main和flavor1的aplication的屬性相結合。 
而在flavor2中所有都齊全,只是label不同,這里使用replace就會把main里面的application的屬性全都替換掉。

如果在application中使用這兩個屬性,除了會把application的屬性和main的清單文件里面的application屬性結合以往,還會把application包含的activity,service等都結合,所有在這里要謹慎使用。

還可以使用其他屬性來進行結合,具體可以去查看Google的開發者文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM