安卓build variant Gradle for Android( 構建變體 )

當你在開發一個app,通常你會有幾個版本。大多數情況是你需要一個開發版本,用來測試app和弄清它的質量,然后還需要一個生產版本。這些版本通常有不同的設置,例如不同的URL地址。更可能的是你可能需要一個免費版和收費版本?;諫鮮鑾榭?,你需要處理不同的版本:開發免費版,開發付費版本,生產免費版,生產付費版,而針對不同的版本不同的配置,這極大增加的管理難度。

Gradle有一些方便的方法來管理這些問題。我們很早之前談過debug和release版本,現在我們談到另外一個概念,不同的產品版本。構建版本和生產版本通??梢院喜?,構建版本和生產版本的合并版叫做構建變種。

這一章我們將學習構建版本,它能使得開發更有效率,并且學習如何使用它們。然后我們會討論構建版本和生產版本的不同,以及如何將其合并。我們會探討簽名機制,如何針對不同的變種簽名等。

在這一章,我們遵循如下規則:

  • Build types

  • Product flavors

  • Build variants

  • Signing configurations

  • 構建版本

    香港彩票透码 www.kptln.icu 在Gradle的Android插件中,一個構建版本意味著定義一個app或者依賴庫如何被構建。每個構建版本都要特殊的一面,比如是否需要debug,application id是什么,是否不需要的資源被刪除等等。你可以定義一個構建版本通過buildTypes方法。例如:

    android {
           buildTypes {
               release {
                   minifyEnabled false
                   proguardFiles getDefaultProguardFile
                     ('proguard-android.txt'), 'proguard-rules.pro'
               }
            }
     }

    這個文件定義了該??槭莚elease版本,然后定義了proguard的位置。該release版本不是唯一的構建版本,默認情況下,還有個debug版本。Android studio把它視為默認構建版本。

    創建自己的構建版本

    當默認的構建版本不夠用的時候,創建版本也是很容易的一件事,創建構建版本你只需要在buildTypes寫入自己的版本。如下所示:

    android {
        buildTypes {
            staging {
                applicationIdSuffix ".staging"
                versionNameSuffix "-staging"
                buildConfigField "String", "API_URL",
                "\"//staging.example.com/api\""
             }
        }
    }

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

  • Debug: com.package

  • Release: com.package

  • Staging: com.package.staging

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

    android {
           buildTypes {
               staging.initWith(buildTypes.debug)
               staging {
                   applicationIdSuffix ".staging"
                   versionNameSuffix "-staging"
                   debuggable = false
               } 
            }
    }

    initWith()方法創建了一個新的版本的同時,復制所有存在的構建版本,類似繼承。我們也可以復寫該存在版本的所有屬性。

    Source sets

    當你創建了一個新的構建版本,Gradle也創建了新的source set。默認情況下,該文件夾不會自動為你創建,所有你需要手工創建。

    app
    └── src
    ├── debug
    │ ├── java
           │   │   └── com.package
     │ │
    │ ├── res
    │ │ └── layout
    │   │       └── activity_main.xml
    │   └── AndroidManifest.xml
    ├── main
    │ ├── java
    │   │   └── com.package
    │ │
    │ ├── res
    └── MainActivity.java
    └── Constants.java
    │ │
    │ │
    │ │
    │   └── AndroidManifest.xml
    ├── staging
    │ ├── java
    │   │   └── com.package
    ├── drawable
    └── layout
    └── activity_main.xml
    │ │
    │ ├── res
    │ │ └── layout
    │   │       └── activity_main.xml
    │   └── AndroidManifest.xml
    └── release
        ├── java
        │   └── com.package
        │       └── Constants.java
        └── AndroidManifest.xml

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

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

    舉個例子,當你在main中創建了一個srings.xml的時候:

    <resources>
           <string name="app_name">TypesAndFlavors</string>
           <string name="hello_world">Hello world!</string>
    </resources>

    當你在你的staing版本也添加了rings.xml:

    <resources>
           <string name="app_name">TypesAndFlavors STAGING</string>
    </resources>

    然后合并的strings.xml將會是這樣的:

    <resources>
           <string name="app_name">TypesAndFlavors STAGING</string>
           <string name="hello_world">Hello world!</string>
    </resources>

    當你創建一個新的構建版本而不是staging,最終的strings.xml將會是main目錄下的strings.xml。

    manifest也和value文件下的文件一樣。如果你為你的構建版本創建了一個manifest文件,那么你不必要去拷貝在main文件下的manifest文件,你需要做的是添加標簽。Android插件將會為你合并它們。

    我們將在會之后的章節講到合并的更多細節。

    依賴包

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

    dependencies {

       compile fileTree(dir: 'libs', include: ['*.jar'])
       compile 'com.android.support:appcompat-v7:22.2.0'
       debugCompile 'de.mindpipe.android:android-logging-log4j:1.0.3'
    }

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

    product flavors

    和構建版本不同,product flavors用來為一個app創建不同版本。典型的例子是,一個app有付費和免費版。product flavors極大簡化了基于相同的代碼構建不同版本的app。

    如果你不確定你是否需要一個新的構建版本或者product flavors,你應該問你自己,你是否需要內部使用和外部使用的apk。如果你需要一個完全新的app去發布,和之前的版本完全隔離開,那么你需要product flavors。否則你只是需要構建版本。

    創建product flavors

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

    android {
        productFlavors {
            red {
                 applicationId 'com.gradleforandroid.red'
                 versionCode 3
            }
            blue {
                 applicationId 'com.gradleforandroid.blue'
                 minSdkVersion 14
                 versionCode 4
            }
        }
    }

    product flavors和構建版本的配置不同。因為product flavors有自己的ProductFlavor類,就像defaultConfig,這意味著你的所有productFlavors都分享一樣的屬性。

    Source sets

    就像構建版本一樣,product Flavors也有自己的代碼文件夾。創建一個特殊的版本就像創建一個文件夾那么簡單。舉個例子,當你有的生產版本的blue flavors有一個不同的app圖標,該文件夾需要被叫做blueRelease。

    多個flavors構建變體

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

     android {
           flavorDimensions "color", "price"
           productFlavors {
               red {
                   flavorDimension "color"
               }
               blue {
                   flavorDimension "color"
               }
               free {
                   flavorDimension "price"
               }
               paid {
                   flavorDimension "price"
               }
           }
    }

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

  • blueFreeDebug and blueFreeRelease

  • bluePaidDebug and bluePaidRelease

  • redFreeDebug and redFreeRelease

  • redPaidDebug and redPaidRelease

  • 構建變體

    構建變體是構建版本和生產版本的結合體。當你創建了一個構建版本或者生產版本,同樣的,新的變體也會被創建。舉個例子,當你有debug和release版本,你創建了red和blue的生產版本,那么變體將會有四個:

    安卓build variant Gradle for Android( 構建變體 )0

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

    如果你沒有product flavors,那么變體只是簡單的包含構建版本,就算你沒有定義任何構建版本,Android studio也會默認為你創建debug版本的。

    tasks

    android插件回味每一個變體創建不同的配置。一個新的Android項目會有debug和release版本,所有你可以使用assembleDebug和assembleRelease,當然當你使用assemble命令,會二者都執行。當你添加了一個新的構建版本,新的task也會被創建。例如:

  • 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

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

    資源文件和manifest的合并

    在打包app之前,Android插件會合并main中的代碼和構建的代碼。當然,依賴項目也可以提供額外的資源,它們也會被合并。你可能需要額外的Android權限針對debug變體。舉個例子,你不想在main中申明這個權限,因為這可能導致一些問題,所以你可以添加一個額外的mainfest文件在debug的文件夾中,申明額外的權限。

    資源和mainfests的優先級是這樣的:

    安卓build variant Gradle for Android( 構建變體 )1

    如果一個資源在main中和在flavor中定義了,那么那個在flavor中的資源有更高的優先級。這樣那個在flavor文件夾中的資源將會被打包到apk。而在依賴項目申明的資源總是擁有最低優先級。

    創建構建變體

    gradle讓處理構建變體變得容易。

    android {
           buildTypes {
               debug {
                   buildConfigField "String", "API_URL",
                   "\"//test.example.com/api\""
            }
               staging.initWith(android.buildTypes.debug)
               staging {
                   buildConfigField "String", "API_URL",
                     "\"//staging.example.com/api\""
                   applicationIdSuffix ".staging"
               }
           }
           productFlavors {
               red {
                   applicationId "com.gradleforandroid.red"
                   resValue "color", "flavor_color", "#ff0000"
               }
               blue {
                   applicationId "com.gradleforandroid.blue"
                   resValue "color", "flavor_color", "#0000ff"
               } 
         }
    }

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

    安卓build variant Gradle for Android( 構建變體 )2

    安卓build variant Gradle for Android( 構建變體 )3

    變體過濾器

    忽略某個變體也是可行的。這樣你可以加速你的構建當使用assemble的時候,這樣你列出的tasks將不會執行那么你不需要的變體。你可以使用過濾器,在build.gradle中添加代碼如下所示:

    android.variantFilter { variant ->
           if(variant.buildType.name.equals('release')) {
               variant.getFlavors().each() { flavor ->
                   if (flavor.name.equals('blue')) { variant.setIgnore(true);
                }
            }
        }
    }

    在這個例子中,我們檢查下:

    安卓build variant Gradle for Android( 構建變體 )4

    你可以看到blueFreeRelease和bluePaidRelease被排除在外,如果你運行gradlew tasks,你會發現所有的關于上述變體的tasks不再存在。

    簽名配置

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

       android {
           signingConfigs {
               staging.initWith(signingConfigs.debug)
               release {
     storeFile file("release.keystore")
     storePassword"secretpassword"
     keyAlias "gradleforandroid"
     keyPassword "secretpassword"
     }
     }
    }

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

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

    當你定義了簽名配置后,你需要應用它們。構建版本都有一個屬性叫做signingConfig,你可以這么干:

    android {
           buildTypes {
               release {
                   signingConfig signingConfigs.release
               } 
           }
    }

    上例使用了buildTypes,但是你可能需要對每個版本生成不同的驗證,你可以這么定義:

    android {
           productFlavors {
               blue {
                   signingConfig signingConfigs.release
               }
           }
    }

    當然,你在flavor中定義這些,最好會被重寫,所以最好的做法是:

    android {
           buildTypes {
               release {
     productFlavors.red.signingConfig signingConfigs.red
     productFlavors.blue.signingConfig signingConfigs.blue
     }
     }
    }

來源:itnose

上一篇: 厲害了我的哥!谷歌推出傻瓜式開發工具

下一篇: 安卓7.1.1更新內容大全:Nexus用上Pixel新特性

分享到: 更多
平刷王时时彩软件 上海时时哪里买的 七乐彩基本走势图 凯利指数 幸运飞艇冠军计划免费软件 电子游戏平台网址大全 足球即时比 双色球开奖直播现场 2017年3d走势图带连线 棋牌斗牛如何看牌抢庄 福建时时分析软件 登录北京时时开奖结果 免费赛车计划软件下载 麻将下载 时时彩赚钱秘籍 七乐彩走势图下期预测