配置Gradle構建
這一節是在 android構建系統總覽 和 用Android Studio構建及運行android app 之上構建起來的,它向你展示了如何使用基于product flavors和build types的build variants。
構建配置基礎
Android Studio項目包含一個頂層的構建文件,而每個模塊也都有自己的構建文件。構建文件被稱為build.gradle,它們是純文本文件,使用Groovy語法通過Gradle的Android插件提供的元素來配置構建過程。在大多數情況下,你只需要編輯模塊級的構建文件。比如,在BuildSystemExample項目里,app模塊的構建文件是這樣的:
apply plugin: 'com.android.application'android { compileSdkVersion 19 buildToolsVersion "19.0.0"
defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
}
dependencies { compile project(":lib") compile 'com.android.support:appcompat-v7:19.0.1' compile fileTree(dir: 'libs', include: ['*.jar']) }</pre>
apply plugin: 'com.android.application'為這次構建應用Gradle的Android插件。這一行向頂層構建tasks中添加了Android特有的構建tasks,并使得android {...}元素能夠描述Android特有的構建選項。
android {...}配置了所有Android特有的構建選項:
compileSdkVersion屬性指定了編譯目標。
buildToolsVersion屬性指定了使用的構建工具的版本。要安裝多個版本的構建工具,請使用SDK Manager。注意:請總是使用主修訂版本號大于等于你的編譯目標和目標SDK的構建工具。
defaultConfig元素在構建系統中動態地配置manifest文件(AndroidManifest.xml)中的核心設定及項(entries)。defaultConfig中的值會覆蓋manifest文件中的值。defaultConfig元素中描述的配置項應用于所有的build variants,除非一個build variant的配置覆蓋了這些值。
buildTypes元素控制如何構建及打包你的app。默認情況下,構建系統定義了兩種build types:debug和release。debug build type包含了調試的符號信息并用debug key簽名。默認情況下release build type不簽名。在這個例子中,構建文件配置了使用ProGuard的release版本。
dependencies元素在android元素的外面,且在它的后面。這個元素聲明了這個模塊的依賴(dependencies)。下面的部分會來講解依賴(dependencies)。
注意:當對你項目中的構建文件做了修改,Android Studio會請求一個projec sync來導入構建配置的改動。點擊Android Studio中出現的黃色通知欄上的 Sync Now來導入變動。
圖1. 于Android Studio中同步project
聲明依賴
這個例子中的app模塊聲明了三個依賴:
... dependencies { // Module dependency compile project(":lib")// Remote binary dependency compile 'com.android.support:appcompat-v7:19.0.1' // Local binary dependency compile fileTree(dir: 'libs', include: ['*.jar'])
}</pre>
這些依賴都將在下面進行描述。構建系統會把所有的compile依賴都添加到編譯的classpath中,并把它們都包含進最終的包里。
模塊依賴
app模塊依賴lib模塊,因為MainActivity要啟動Open an Activity from a Library Module中所描述的LibActivity1。
compile project(":lib")聲明了一個對BuildSystemExample的lib模塊的依賴。當你構建app模塊時,構建系統會匯集并包含lib模塊。
遠程二進制依賴
app和lib模塊都使用了Android Support Library里的ActionBarActivity類,因而這些模塊都依賴于它。
compile 'com.android.support:appcompat-v7:19.0.1'通過指定它的Maven坐標聲明了一個對于版本為19.0.1的Android Support Library的依賴。Android Support Library能在Android SDK的Android Repository包中找到。如果你的SDK包中沒有這個包,請使用SDK Manager下載并安裝它。
本地二進制依賴
有些模塊不使用本地文件系統上的任何二進制依賴。如果你有模塊需要本地的二進制依賴,請把這些依賴的JAR文件復制到你的項目的<moduleName>/libs目錄下。
compile fileTree(dir: 'libs', include: ['*.jar'])告訴構建系統app/libs里的所有JAR文件都是必需的,且應該被包含進編譯classpath及最終的包里面。
更多關于 Gradle里的依賴的信息,請參考Gradle用戶指南(Gradle User Guide)里的Dependency Management Basics。
運行ProGuard
構建系統可以在構建過程中運行ProGuard來混淆你的類。在BuildSystemExample中,修改app模塊的構建文件為release build運行ProGuard:
... android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } ...getDefaultProguardFile('proguard-android.txt')從Android SDK包中獲取默認的ProGuard設置。Android Studio會添加位于模塊的根目錄的模塊特有規則文件proguard-rules.pro,你可以向這個文件中添加定制的ProGuard規則。
用應用程序ID標識包
在Android構建系統中,applicationId屬性用于為發布唯一地標識應用程序包。應用程序ID在build.gradle文件的android段設置。
apply plugin: 'com.android.application'android { compileSdkVersion 19 buildToolsVersion "19.1" defaultConfig { applicationId "com.example.my.app" minSdkVersion 15 targetSdkVersion 19 versionCode 1 versionName "1.0" } ...</pre> <p><span style="font-size:16px;"><strong>注意</strong>,<span style="font-size:16px;"><em>applicationId</em></span>只在你的build.gradle文件中設置,而不是AndroidManifest.xml文件中。</span> </p>
當使用build variants時,構建系統使你能為每種product flavors和build type唯一地標識不同的包。build type中的應用程序ID會被作為一個后綴添加到product flavors的應用程序ID上。
productFlavors { pro { applicationId = "com.example.my.pkg.pro" } free { applicationId = "com.example.my.pkg.free" } }buildTypes { debug { applicationIdSuffix ".debug" } } ....</pre> <p><span style="font-size:16px;">包名仍然必須在manifest文件中指定。它在你的源代碼中使用,用于引用你的R類,及解析任何相關的activity/service注冊。</span> </p>
package="com.example.app">注意:如果你有多個manifests(比如,一個product flavor特有的manifest及一個build type manifest),那些manifests里的包名是可選的。如果在那些manifest里指定了包名,則它們必須與src/main/目錄下的manifest文件中指定的包名一致。
配置簽名設定
app的debug和release版本,不僅在 是否能在安全的設備上被調試 這一點是不同的,它們的APK的簽名方法也是不同的。構建系統使用已知的認證信息(credentials)通過一個默認的key和證書(certificate)來簽名debug版以避免在構建的時候彈出一個密碼提示框。構建系統不簽名release版,除非顯式地為這次構建定義一個簽名配置。如果你沒有release key,你可以按照Signing your Applications中描述的那樣生成一個。
使用build variants
這一部分描述構建系統如何幫助你由一個單獨項目創建相同應用程序的不同版本。當你的app有一個演示版及一個付費版時,或者你想要在Google Play上為不同的設備配置分發多個APKs時這很有用。
構建系統使用product flavors來創建你的app的不同產品版本。你的app的每個產品版本可以具有不同的功能或設備要求。構建系統也對每個產品版本使用build types來應用不同的構建及打包設定。每個product flavor和build type組合形成一個build variant。構建系統為你的app的每個build variant產生一個不同的APK。
Build variants
這個示例項目由兩個默認的build types(debug和release)及兩個app類型(demo和full) product flavors組成。關于build variants的高級使用的更多信息,請參考 android構建系統總覽。
Product flavors
創建你的app的不同產品版本:
- 在構建文件(build file)中定義product flavors。
- 為每個flavor創建額外的源碼目錄。
- 添加flavor特有的源碼進你的項目。
</ol>這一節的其余部分將使用一個BuildSystemExample項目帶你詳細地了解這些步驟。你為BuildSystemExample app創建兩個flavors,一個demo flavor和一個full flavor。這兩個Flavors共享MainActivity,你在它里面添加一個新的按鈕來啟動一個新的activity,SecondActivity。不同flavor的這個新activity是不同的,因而你模擬這樣一種情形,即full flavor中的這個新activity相比于demo flavor中的那個將具有更多的功能。在這個練習的最后,你以兩個不同的APKs結束,每個flavor一個。
在構建文件(build file)中定義product flavors
要定義兩個product flavors,則編輯app模塊的構建文件(build file)并添加如下的配置:
... android { ... defaultConfig { ... } signingConfigs { ... } buildTypes { ... } productFlavors { demo { applicationId "com.buildsystemexample.app.demo" versionName "1.0-demo" } full { applicationId "com.buildsystemexample.app.full" versionName "1.0-full" } } } ...product flavor定義支持與defaultConfig元素相同的屬性。所有flavors的基本配置在defaultConfig中指定,而每個flavor則可以覆蓋默認值。上面的構建文件(build file)使用了applicationId屬性來為每個flavor分配一個不同的包名:因為每個flavor定義創建一個不同的app,它們都需要一個不同的包名。
注意:要在Google Play中使用Multiple APK Support分發你的app,則請為所有的variants分配相同的包名,并為每個variant提供一個不同versionCode。要在Google Play中以不同的apps分發你的app的不同變體(variant),則為每個variant分配一個不同的包名。
為每個flavor添加額外的源碼目錄
現在你需要為每個flavor創建源碼目錄并添加一個SecondActivity。要為demo flavor創建源碼目錄結構則執行:
- 在Project面板,展開BuildSystemExample,然后展開app目錄。
- 右鍵單擊app下的src目錄并選擇New > Directory。
- 鍵入"demo"作為新目錄的名字并點擊OK。
- 類似地,創建下面的這些目錄:
</ol>
- app/src/demo/java
- app/src/demo/res
- app/src/demo/res/layout
- app/src/demo/res/values
</ul>最終的目錄結構看上去如下圖1所示的那樣。
圖1. demo flavor的新源碼目錄
給每個flavor添加一個新的activity
給demo flavor添加SecondActivity:
- 在Project面板,右鍵單擊app模塊并選擇 New > Activity。
- 選擇Blank Activity并點擊Next。
- 鍵入"SecondActivity"作為activity名字。
- 鍵入"com.buildsystemexample.app"作為包名并點擊Finish。
- 右鍵單擊app/src/demo下的java目錄并選擇New > Package。
- 鍵入"com.buildsystemexample.app"作為包名并點擊OK。
- 把SecondActivity拖到app/src/demo/java里的新包下。
- 接受默認值并點擊Refactor。
</ol>給demo flavor添加一個字符串資源并為SecondActivity添加layout:
- 把app/src/main/res/layout里的activity_second.xml拖到app/src/demo/res/layout下。
- 接受窗口中出現的默認值并點擊OK。
- 把app/src/main/res下的strings.xml復制到app/src/demo/res里。
- 用下面的內容替換新復制的strings.xml里的內容:
</ol><?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello_world">Demo version only.</string> </resources>現在通過創建一份demo flavor的拷貝來為full flavor添加源碼目錄和SecondActivity:
在Project面板,右鍵單擊app/src下的demo目錄并選擇Copy。
右鍵單擊app/下的/src目錄并選擇Paste。
在出現的窗口中,鍵入"full"作為新的名字并點擊OK。
用下面的內容替換src/full/res/values下的strings.xml里的內容:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello_world">This is the full version!</string> </resources>注意:從現在開始,你可以獨立地開發每個flavor里的SecondActivity了。比如,你可以為full flavor里的這個activity添加更多的功能。
要基于一個特定flavor的文件來工作,則點擊IDE窗口左邊的Build Variants,并選擇Build Variants面板里你想要修改的falvor,如圖2所示的那樣。Android Studio可能顯示在Build Variants面板里被選中之外的flavors源碼文件里有錯誤,但這不影響構建的最終輸出。
圖2. Build Variants面板
從主activity啟動一個flavor特有activity
由于兩個flavors中的flavor特有activity (SecondActivity)具有相同的包名及activity名,你可以在主activity中啟動它,所有flavors的啟動方法一樣。修改主activity的方法:
編輯activity_main.xml給MainActivity添加一個新的按鈕:
<LinearLayout ...> ... <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button2" android:onClick="onButton2Clicked"/> </LinearLayout>點擊layout文件中標紅的區域并按下Alt+ Enter。遵循Android Studio的提示,添加一個值為“Open Second Activity”的新字符串資源,并給MainActivity添加一個onButton2Clicked方法。
把下面的代碼添加進MainActivity的onButton2Clicked方法:
public void onButton2Clicked(View view) { Intent intent = new Intent(this, SecondActivity.class); startActivity(intent)</span>編輯app的manifest包含一個對SecondActivity的引用:
<manifest ...> <application ...> ... <activity android:name="com.buildsystemexample.app.SecondActivity" android:label="@string/title_activity_second" > </activity> </application> </manifest>Build types
Build types表示為每個app包產生的構建打包版本(build packaging versions)。默認提供了debug和release兩個build types。
... android { ... defaultConfig { ... } signingConfigs { ... } buildTypes { ... } productFlavors {...} buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { debuggable true } } } ...注意:盡管只有release build type出現在默認的build.gradle文件里,但每次構建都會應用release和debug兩個build types。
在這個例子里,product flavors和build types創建了如下的build variants:
- demoDebug
- demoRelease
- fullDebug
- fullRelease
</ul>要構建這個例子,請點擊Build菜單選項,或者在命令行上調用assemble task。
注意: Build > Make Project選項編譯整個項目中自上次編譯以來被修改過的所有的源文件。Build > Rebuild Project選項重編譯項目中的所有源文件。
每個build variants會有不同的輸出文件夾創建出來。
Android Studio默認配置項目使用Maven Central Repository。(這個配置被包含在項目的頂層build file中。)
Done。
原文。