2015-05-14 52 views
12

鑑於以下配置:搖籃buildType/productFlavor使用意想不到buildConfigField

productFlavors { 
    normal { 
    applicationId "com.app" 
    } 

    mock { 
    applicationId "com.app.mock" 
    } 
} 

buildTypes { 
    debug { 
    productFlavors.normal.buildConfigField "boolean", "mockMode", "false" 
    productFlavors.mock.buildConfigField "boolean", "mockMode", "true" 
    } 

    release { 
    productFlavors.normal.buildConfigField "boolean", "mockMode", "false" 
    // Release should never point to mocks. Ever. 
    productFlavors.mock.buildConfigField "boolean", "mockMode", "false" 
    } 
} 

enter image description here

我本來期望BuildConfig.mockMode = true;,然而,這是最終構建配置:

public final class BuildConfig { 
    public static final boolean DEBUG = Boolean.parseBoolean("true"); 
    public static final String APPLICATION_ID = "*****"; 
    public static final String BUILD_TYPE = "debug"; 
    public static final String FLAVOR = "mock"; 
    public static final int VERSION_CODE = 1; 
    public static final String VERSION_NAME = "1.0"; 
    // Fields from product flavor: mock 
    public static final boolean mockMode = false; 
} 

從一些調查/調試,我意識到,如果我實際上在發佈buildType中更改產品風格的值儘管mockDebug被選爲我的構建變體,但更新了BuildConfig.mockMode的值。

我已經實現了我想做一個更好的解決方案,所以我只是在尋找一個答案,可以幫助我瞭解爲什麼搖籃在這樣基礎上的配置作用,幫助我瞭解更多它在做什麼。

回答

2

非常容易理解的,一旦你有此配置中運行:

buildTypes { 
    debug { 
     println("debug!") 
    } 
    release { 
     println("release!") 
    } 
} 

什麼,你會在構建日誌中看到的是:

Information:Gradle tasks [:app:assembleOneDebug] 
debug! 
release! 
:app:preBuild UP-TO-DATE 
... 

這意味着所有的4行代碼的是因此唯一有效的行是最後2:

productFlavors.normal.buildConfigField "boolean", "mockMode", "false" 
productFlavors.mock.buildConfigField "boolean", "mockMode", "false" 

這導致您的BuildConfig具有:

public static final boolean mockMode = false; 
+0

感謝您的答案,我想它是執行兩個路徑。你知道爲什麼兩個路徑都被執行了嗎?我認爲把它們分開的關鍵在於你可以爲不同版本配置不同的值。 –

3

您可以提取邏輯來確定BuildConfig字段的實際值並將其轉換爲其自己的方法。這樣,DSL配置只有一條線路。它看起來像這樣(未測試 - 期望語法錯誤):

buildTypes { 
    applicationVariants.all { variant -> 
     variant.buildConfigField "boolean", "mockMode", mockMode(variant) 
    } 
} 

def mockMode(variant) { 
    //Return true or false depending on variant.buildType and variant.productFlavors 
} 
+0

這是一個很好的解決方案。你知道爲什麼它似乎在執行所有構建變體中的邏輯,如果它們被明確定義的話(就像問題中那樣)?這對我來說似乎很奇怪,這是有意的行爲。 –