自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Gradle for Android 第四篇( 構(gòu)建變體 )

移動(dòng)開發(fā) Android
這一章我們將學(xué)習(xí)構(gòu)建版本,它能使得開發(fā)更有效率,并且學(xué)習(xí)如何使用它們。然后我們會(huì)討論構(gòu)建版本和生產(chǎn)版本的不同,以及如何將其合并。我們會(huì)探討簽名機(jī)制,如何針對(duì)不同的變種簽名等。

當(dāng)你在開發(fā)一個(gè)app,通常你會(huì)有幾個(gè)版本。大多數(shù)情況是你需要一個(gè)開發(fā)版本,用來測(cè)試app和弄清它的質(zhì)量,然后還需要一個(gè)生產(chǎn)版本。這些版本通常有不同的設(shè)置,例如不同的URL地址。更可能的是你可能需要一個(gè)免費(fèi)版和收費(fèi)版本。基于上述情況,你需要處理不同的版本:開發(fā)免費(fèi)版,開發(fā)付費(fèi)版本,生產(chǎn)免費(fèi)版,生產(chǎn)付費(fèi)版,而針對(duì)不同的版本不同的配置,這極大增加的管理難度。

Gradle有一些方便的方法來管理這些問題。我們很早之前談過debug和release版本,現(xiàn)在我們談到另外一個(gè)概念,不同的產(chǎn)品版本。構(gòu)建版本和生產(chǎn)版本通常可以合并,構(gòu)建版本和生產(chǎn)版本的合并版叫做構(gòu)建變種。

這一章我們將學(xué)習(xí)構(gòu)建版本,它能使得開發(fā)更有效率,并且學(xué)習(xí)如何使用它們。然后我們會(huì)討論構(gòu)建版本和生產(chǎn)版本的不同,以及如何將其合并。我們會(huì)探討簽名機(jī)制,如何針對(duì)不同的變種簽名等。

在這一章,我們遵循如下規(guī)則:

  • Build types
  • Product flavors
  • Build variants
  • Signing configurations

構(gòu)建版本

在Gradle的Android插件中,一個(gè)構(gòu)建版本意味著定義一個(gè)app或者依賴庫(kù)如何被構(gòu)建。每個(gè)構(gòu)建版本都要特殊的一面,比如是否需要debug,application id是什么,是否不需要的資源被刪除等等。你可以定義一個(gè)構(gòu)建版本通過buildTypes方法。例如:

  1. android { 
  2.        buildTypes { 
  3.            release { 
  4.                minifyEnabled false 
  5.                proguardFiles getDefaultProguardFile 
  6.                  ('proguard-android.txt'), 'proguard-rules.pro' 
  7.            } 
  8.         } 
  9.  }  

這個(gè)文件定義了該模塊是release版本,然后定義了proguard的位置。該release版本不是唯一的構(gòu)建版本,默認(rèn)情況下,還有個(gè)debug版本。Android studio把它視為默認(rèn)構(gòu)建版本。

創(chuàng)建自己的構(gòu)建版本

當(dāng)默認(rèn)的構(gòu)建版本不夠用的時(shí)候,創(chuàng)建版本也是很容易的一件事,創(chuàng)建構(gòu)建版本你只需要在buildTypes寫入自己的版本。如下所示:

  1. android { 
  2.     buildTypes { 
  3.         staging { 
  4.             applicationIdSuffix ".staging" 
  5.             versionNameSuffix "-staging" 
  6.             buildConfigField "String""API_URL"
  7.             "\"http://staging.example.com/api\"" 
  8.          } 
  9.     } 
  10.  

我們定義了一個(gè)staging版本,該版本定義了一個(gè)新的application id,這讓其與debug和release版本的applicationID不同。假設(shè)你使用了默認(rèn)的配置,那么applicationID將會(huì)是這樣的:

  • Debug: com.package
  • Release: com.package
  • Staging: com.package.staging

這意味著你可以在你的設(shè)備上安裝staging版本和release版本。staging版本也有自己的版本號(hào)。buildConfigField定義了一個(gè)新的URL地址。你不必事事都去創(chuàng)建,所以最可能的方式是去繼承已有的版本。 

  1. android { 
  2.        buildTypes { 
  3.            staging.initWith(buildTypes.debug) 
  4.            staging { 
  5.                applicationIdSuffix ".staging" 
  6.                versionNameSuffix "-staging" 
  7.                debuggable = false 
  8.            }  
  9.         } 
  10.  

initWith()方法創(chuàng)建了一個(gè)新的版本的同時(shí),復(fù)制所有存在的構(gòu)建版本,類似繼承。我們也可以復(fù)寫該存在版本的所有屬性。

Source sets

當(dāng)你創(chuàng)建了一個(gè)新的構(gòu)建版本,Gradle也創(chuàng)建了新的source set。默認(rèn)情況下,該文件夾不會(huì)自動(dòng)為你創(chuàng)建,所有你需要手工創(chuàng)建。

  1. app 
  2. └── src 
  3. ├── debug 
  4. │ ├── java 
  5.        │   │   └── com.package 
  6.  │ │ 
  7. │ ├── res 
  8. │ │ └── layout 
  9. │   │       └── activity_main.xml 
  10. │   └── AndroidManifest.xml 
  11. ├── main 
  12. │ ├── java 
  13. │   │   └── com.package 
  14. │ │ 
  15. │ ├── res 
  16. └── MainActivity.java 
  17. └── Constants.java 
  18. │ │ 
  19. │ │ 
  20. │ │ 
  21. │   └── AndroidManifest.xml 
  22. ├── staging 
  23. │ ├── java 
  24. │   │   └── com.package 
  25. ├── drawable 
  26. └── layout 
  27. └── activity_main.xml 
  28. │ │ 
  29. │ ├── res 
  30. │ │ └── layout 
  31. │   │       └── activity_main.xml 
  32. │   └── AndroidManifest.xml 
  33. └── release 
  34.     ├── java 
  35.     │   └── com.package 
  36.     │       └── Constants.java 
  37.     └── AndroidManifest.xml  

注意:當(dāng)你添加一個(gè)Java類的時(shí)候,你需要知道以下過程,當(dāng)你添加了CustomLogic.java到staging版本,你可以添加相同的類到debug和release版本,但是不能添加到main版本。如果你添加了,會(huì)拋出異常。

當(dāng)使用不同的source sets的時(shí)候,資源文件的處理需要特殊的方式。Drawables和layout文件將會(huì)復(fù)寫在main中的重名文件,但是values文件下的資源不會(huì)。gradle將會(huì)把這些資源連同main里面的資源一起合并。

舉個(gè)例子,當(dāng)你在main中創(chuàng)建了一個(gè)srings.xml的時(shí)候:

  1. <resources> 
  2.        <string name="app_name">TypesAndFlavors</string> 
  3.        <string name="hello_world">Hello world!</string> 
  4. </resources>  

當(dāng)你在你的staing版本也添加了rings.xml:

  1. <resources> 
  2.        <string name="app_name">TypesAndFlavors STAGING</string> 
  3. </resources>  

然后合并的strings.xml將會(huì)是這樣的:

  1. <resources> 
  2.        <string name="app_name">TypesAndFlavors STAGING</string> 
  3.        <string name="hello_world">Hello world!</string> 
  4. </resources>  

當(dāng)你創(chuàng)建一個(gè)新的構(gòu)建版本而不是staging,最終的strings.xml將會(huì)是main目錄下的strings.xml。

manifest也和value文件下的文件一樣。如果你為你的構(gòu)建版本創(chuàng)建了一個(gè)manifest文件,那么你不必要去拷貝在main文件下的manifest文件,你需要做的是添加標(biāo)簽。Android插件將會(huì)為你合并它們。

我們將在會(huì)之后的章節(jié)講到合并的更多細(xì)節(jié)。

依賴包

每一個(gè)構(gòu)建版本都有自己的依賴包,gradle自動(dòng)為每一個(gè)構(gòu)建的版本創(chuàng)建不同的依賴配置。如果你想為debug版本添加一個(gè)logging框架,你可以這么做:

  1. dependencies { 
  2.  
  3.    compile fileTree(dir: 'libs', include: ['*.jar']) 
  4.    compile 'com.android.support:appcompat-v7:22.2.0' 
  5.    debugCompile 'de.mindpipe.android:android-logging-log4j:1.0.3' 
  6.  

你可以結(jié)合不同的構(gòu)建版本著不同的構(gòu)建配置,就像這種方式,這讓你的不同版本的不同依賴包成為可能。

product flavors

和構(gòu)建版本不同,product flavors用來為一個(gè)app創(chuàng)建不同版本。典型的例子是,一個(gè)app有付費(fèi)和免費(fèi)版。product flavors極大簡(jiǎn)化了基于相同的代碼構(gòu)建不同版本的app。

如果你不確定你是否需要一個(gè)新的構(gòu)建版本或者product flavors,你應(yīng)該問你自己,你是否需要內(nèi)部使用和外部使用的apk。如果你需要一個(gè)完全新的app去發(fā)布,和之前的版本完全隔離開,那么你需要product flavors。否則你只是需要構(gòu)建版本。

創(chuàng)建product flavors

創(chuàng)建product flavors非常的容易。你可以在productFlavors中添加代碼:

  1. android { 
  2.     productFlavors { 
  3.         red { 
  4.              applicationId 'com.gradleforandroid.red' 
  5.              versionCode 3 
  6.         } 
  7.         blue { 
  8.              applicationId 'com.gradleforandroid.blue' 
  9.              minSdkVersion 14 
  10.              versionCode 4 
  11.         } 
  12.     } 
  13.  

product flavors和構(gòu)建版本的配置不同。因?yàn)閜roduct flavors有自己的ProductFlavor類,就像defaultConfig,這意味著你的所有productFlavors都分享一樣的屬性。

Source sets

就像構(gòu)建版本一樣,product Flavors也有自己的代碼文件夾。創(chuàng)建一個(gè)特殊的版本就像創(chuàng)建一個(gè)文件夾那么簡(jiǎn)單。舉個(gè)例子,當(dāng)你有的生產(chǎn)版本的blue flavors有一個(gè)不同的app圖標(biāo),該文件夾需要被叫做blueRelease。

多個(gè)flavors構(gòu)建變體

在一些例子中,你可能需要?jiǎng)?chuàng)建一些product flavors的合并版本。舉個(gè)例子,client A和client B可能都想要一個(gè)free和paid的版本,而他們又都是基于一樣的代碼,但是有不一樣的顏色等。創(chuàng)建四個(gè)不同的flavors意味著有重復(fù)的配置。合并flavors最簡(jiǎn)單的做法可能是使用flavor dimensions,就像這樣:

  1.  android { 
  2.        flavorDimensions "color""price" 
  3.        productFlavors { 
  4.            red { 
  5.                flavorDimension "color" 
  6.            } 
  7.            blue { 
  8.                flavorDimension "color" 
  9.            } 
  10.            free { 
  11.                flavorDimension "price" 
  12.            } 
  13.            paid { 
  14.                flavorDimension "price" 
  15.            } 
  16.        } 

當(dāng)你添加了flavor dimensions,你就需要為每個(gè)flavor添加flavorDimension,否則會(huì)提示錯(cuò)誤。flavorDimensions定義了不同的dimensions,當(dāng)然其順序也很重要。當(dāng)你合并二個(gè)不同的flavors時(shí),他們可能有一樣的配置和資源。例如上例:

  • blueFreeDebug and blueFreeRelease
  • bluePaidDebug and bluePaidRelease
  • redFreeDebug and redFreeRelease
  • redPaidDebug and redPaidRelease

構(gòu)建變體

構(gòu)建變體是構(gòu)建版本和生產(chǎn)版本的結(jié)合體。當(dāng)你創(chuàng)建了一個(gè)構(gòu)建版本或者生產(chǎn)版本,同樣的,新的變體也會(huì)被創(chuàng)建。舉個(gè)例子,當(dāng)你有debug和release版本,你創(chuàng)建了red和blue的生產(chǎn)版本,那么變體將會(huì)有四個(gè): 

 

 

 

你可以在Android studio的左下角找到它,或者通過VIEW|Tool Windows|Build Variants打開它。該視圖列出了所有的變體,并且允許你去切換它們。改變他們將會(huì)影響到你按Run按鈕。

如果你沒有product flavors,那么變體只是簡(jiǎn)單的包含構(gòu)建版本,就算你沒有定義任何構(gòu)建版本,Android studio也會(huì)默認(rèn)為你創(chuàng)建debug版本的。

tasks

android插件回味每一個(gè)變體創(chuàng)建不同的配置。一個(gè)新的Android項(xiàng)目會(huì)有debug和release版本,所有你可以使用assembleDebug和assembleRelease,當(dāng)然當(dāng)你使用assemble命令,會(huì)二者都執(zhí)行。當(dāng)你添加了一個(gè)新的構(gòu)建版本,新的task也會(huì)被創(chuàng)建。例如:

  • assembleBlue uses the blue flavor configuration and assembles both BlueRelease and BlueDebug.
  • assembleBlueDebug combines the flavor configuration with the build type configuration, and the flavor settings override the build type settings.

Source sets

構(gòu)建變體也可以有自己的資源文件夾,舉個(gè)例子,你可以有src/blueFreeDebug/java/。

資源文件和manifest的合并

在打包app之前,Android插件會(huì)合并main中的代碼和構(gòu)建的代碼。當(dāng)然,依賴項(xiàng)目也可以提供額外的資源,它們也會(huì)被合并。你可能需要額外的Android權(quán)限針對(duì)debug變體。舉個(gè)例子,你不想在main中申明這個(gè)權(quán)限,因?yàn)檫@可能導(dǎo)致一些問題,所以你可以添加一個(gè)額外的mainfest文件在debug的文件夾中,申明額外的權(quán)限。

資源和mainfests的優(yōu)先級(jí)是這樣的: 

 

 

 

如果一個(gè)資源在main中和在flavor中定義了,那么那個(gè)在flavor中的資源有更高的優(yōu)先級(jí)。這樣那個(gè)在flavor文件夾中的資源將會(huì)被打包到apk。而在依賴項(xiàng)目申明的資源總是擁有***優(yōu)先級(jí)。

創(chuàng)建構(gòu)建變體

gradle讓處理構(gòu)建變體變得容易。

  1. android { 
  2.        buildTypes { 
  3.            debug { 
  4.                buildConfigField "String""API_URL"
  5.                "\"http://test.example.com/api\"" 
  6.         } 
  7.            staging.initWith(android.buildTypes.debug) 
  8.            staging { 
  9.                buildConfigField "String""API_URL"
  10.                  "\"http://staging.example.com/api\"" 
  11.                applicationIdSuffix ".staging" 
  12.            } 
  13.        } 
  14.        productFlavors { 
  15.            red { 
  16.                applicationId "com.gradleforandroid.red" 
  17.                resValue "color""flavor_color""#ff0000" 
  18.            } 
  19.            blue { 
  20.                applicationId "com.gradleforandroid.blue" 
  21.                resValue "color""flavor_color""#0000ff" 
  22.            }  
  23.      } 
  24.  

在這個(gè)例子中,我們創(chuàng)建了4個(gè)變體,分別是blueDebug,blueStaging,redDebug,redStaging。每一個(gè)變體都有其不同的api url以及顏色。例如: 

 

 

 

 

 

 

 

變體過濾器

忽略某個(gè)變體也是可行的。這樣你可以加速你的構(gòu)建當(dāng)使用assemble的時(shí)候,這樣你列出的tasks將不會(huì)執(zhí)行那么你不需要的變體。你可以使用過濾器,在build.gradle中添加代碼如下所示:

  1. android.variantFilter { variant -> 
  2.        if(variant.buildType.name.equals('release')) { 
  3.            variant.getFlavors().each() { flavor -> 
  4.                if (flavor.name.equals('blue')) { variant.setIgnore(true); 
  5.             } 
  6.         } 
  7.     } 
  8.  

在這個(gè)例子中,我們檢查下: 

 

 

 

你可以看到blueFreeRelease和bluePaidRelease被排除在外,如果你運(yùn)行g(shù)radlew tasks,你會(huì)發(fā)現(xiàn)所有的關(guān)于上述變體的tasks不再存在。

簽名配置

在你發(fā)布你的應(yīng)用之前,你需要為你的app私鑰簽名。如果你有付費(fèi)版和免費(fèi)版,你需要有不同的key去簽名不同的變體。這就是配置簽名的好處。配置簽名可以這樣定義:

  1.  android { 
  2.        signingConfigs { 
  3.            staging.initWith(signingConfigs.debug) 
  4.            release { 
  5.                storeFile file("release.keystore"
  6.                storePassword"secretpassword" 
  7.                keyAlias "gradleforandroid" 
  8.                keyPassword "secretpassword" 
  9.            } 
  10.       } 
  11.  

在這個(gè)例子中,我們創(chuàng)建了2個(gè)不同的簽名配置。debug配置是as默認(rèn)的,其使用了公共的keystore和password,所以沒有必要為debug版本創(chuàng)建簽名配置了。staging配置使用了initWith()方法,其會(huì)復(fù)制其他的簽名配置。這意味著staging和debug的key是一樣的。

release配置使用了storeFile,定義了key alias和密碼。當(dāng)然這不是一個(gè)好的選擇,你需要在 Gradle properties文件中配置。

當(dāng)你定義了簽名配置后,你需要應(yīng)用它們。構(gòu)建版本都有一個(gè)屬性叫做signingConfig,你可以這么干:

  1. android { 
  2.        buildTypes { 
  3.            release { 
  4.                signingConfig signingConfigs.release 
  5.            }  
  6.        } 
  7.  

上例使用了buildTypes,但是你可能需要對(duì)每個(gè)版本生成不同的驗(yàn)證,你可以這么定義:

  1. android { 
  2.        productFlavors { 
  3.            blue { 
  4.                signingConfig signingConfigs.release 
  5.            } 
  6.        } 
  7.  

當(dāng)然,你在flavor中定義這些,***會(huì)被重寫,所以***的做法是:

  1. android { 
  2.        buildTypes { 
  3.            release { 
  4.                productFlavors.red.signingConfig signingConfigs.red 
  5.                productFlavors.blue.signingConfig signingConfigs.blue 
  6.            } 
  7.        } 
  8.  

總結(jié)

在這一章,我們討論了構(gòu)建版本和生產(chǎn)版本,以及如何結(jié)合它們。這將會(huì)是非常有用的工具,當(dāng)你需要不同的url以及不同的keys,而你們有相同的代碼和資源文件,但是有不同的類型以及版本,構(gòu)建版本和生產(chǎn)版本將會(huì)讓你的生活更美好。

我們也談?wù)摿撕灻渲靡约叭绾问褂盟麄儭?/p>

下一章,你將會(huì)學(xué)習(xí)到多模塊構(gòu)建,因?yàn)楫?dāng)你想把你的代碼分成一個(gè)依賴包或者依賴項(xiàng)目的時(shí)候,或者你想把Android wear模塊放在你的應(yīng)用的時(shí)候,這將非常重要。 

責(zé)任編輯:龐桂玉 來源: Android開發(fā)中文站
相關(guān)推薦

2014-03-28 14:13:31

Android開源項(xiàng)目測(cè)試工具

2011-06-23 10:25:38

Oracle

2013-05-07 09:31:14

Hyper-V災(zāi)難恢復(fù)

2017-04-13 14:55:07

AndroidGradle多模塊構(gòu)建

2013-07-18 17:00:12

Gradle構(gòu)建AndAndroid開發(fā)Android學(xué)習(xí)

2011-05-16 14:12:30

QuickWidgetQML

2020-11-19 07:51:06

StringJoine分隔符使用

2017-04-10 14:46:29

AndroidGradleBuild.gradl

2023-05-23 18:11:12

Rust數(shù)組元組

2013-10-23 13:25:28

AngularJS應(yīng)用

2017-04-10 13:43:34

AndroidGradleAS

2017-04-10 17:35:54

AndroidGradle依賴管理

2012-04-25 16:51:21

2011-08-29 13:52:15

李洋Android應(yīng)用

2012-06-12 10:43:20

Windows Pho

2015-03-20 10:01:50

Android StuGradle

2023-12-19 13:13:16

人工智能

2011-06-22 15:04:28

JAVA

2011-04-13 13:38:57

選項(xiàng)APIBlackBerry

2011-05-13 11:17:18

javascript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)