2013-10-10 71 views
17

在構建Android項目之前,我已經爲兩個不同的應用程序付費並免費。使用gradle構建android,替換字符串中的每個產品的風格

我改變了每個值和字符串,所以昨天我犯了一個大錯誤。

所以,我在如何使用gradle構建我的應用程序。

我的應用程序有一些不同。

  1. 應用程序名稱(只需加後綴 ' - 免費') - >值/ string.xml

  2. 改變標誌在我*的.java

// signingConfigs是中省略。

productFlavors{ 
    free{ 
     packageName "my.app.free" 
     versionCode 20 
     signingConfig signingConfigs.freeConfing 

     copy{ 
      from('/res'){ 
       include '**/*.xml' 
      } 
      into 'build/res/' 

      filter{ 
       String line -> line.replaceAll("android:label=\"@string/app_name\"", "android:label=\"@string/app_name_free\"") 
      } 
     } 
     copy{ 
      from('/src'){ 
       include '**/*.java' 
      } 
      into 'build/src/' 

      filter{ 
       String line -> line.replaceAll("public static final Boolean IS_FULL_VER = true;", "public static final Boolean IS_FULL_VER = false;") 
      } 
     } 
    } 
    paid{ 
     packageName "my.app.paid" 
     versionCode 20 
     signingConfig signingConfigs.paidConfing 
    } 
} 

但是,構建的應用程序根本沒有改變。

我錯過了什麼?

回答

52

參見product flavors文檔:

http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors

在你build.gradle,在每個味道,你可以定義旗子在BuildConfig.java文件中生成:

productFlavors { 
    free { 
     packageName "com.company.appfree" 
     buildConfig "public final static com.company.common.MonetizationType monetizationType = com.company.common.MonetizationType.FREE;" 
    } 

    paid { 
     packageName "com.company.apppaid" 
     buildConfig "public final static com.company.common.MonetizationType monetizationType = com.company.common.MonetizationType.PAID;" 
    } 
} 

此示例使用enum(你需要在你的java代碼中定義某處):

public enum MonetizationType { 
    PAID, FREE 
} 

現在,您可以在任何地方使用這樣的:

使用以下結構

if (BuildConfig.monetizationType == MonetizationType.FREE) { ... } 

用於覆蓋資源,可以爲每個風味源文件夾中創建不同的資源文件

app/build.gradle 
app/ [.. some other files...] 
app/src/main/ 
app/src/main/java 
app/src/main/res 
app/src/main/assets 
app/src/main/AndroidManifest.xml 


app/src/free/res/values/apptitle.xml 
app/src/paid/res/values/apptitle.xml 

apptitle.xml將是一個字符串資源文件(就像strings.xml),但與o只有一個字符串:你想要根據風味而不同。 (你不需要在你的main/res目錄中有一個apptitle.xml)。

<?xml version="1.0" encoding="utf-8"?> 
<resources xmlns:tools="http://schemas.android.com/tools"> 
    <string name="app_title">App Title (or whatever you want)</string> 
</resources> 

您可能能夠覆蓋不同的方式串,但我喜歡保持重寫字符串從休息清晰分開。

+0

謝謝!現在我可以用不同的貨幣化類型構建。但我無法更改我的應用程序名稱。我的項目結構與此不相同。在我的項目中,**/src/my/app/**/*。java,/res/values/string.xml**。這是Maven項目結構嗎?我可以改變項目結構嗎? –

+0

我的項目結構是新的Android Studio/Gradle項目結構。請參閱文檔http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors。它應該解釋一切。是的,你可能不得不改變你的文件夾,但這並不難。爲android studio創建一個新的示例項目,並查看該build.gradle文件以及目錄設置的方式。然後改變你的項目以反映這種結構。 – treesAreEverywhere

+0

如何參考AndroidManifest.xml中的app_title?我嘗試了@ apptitle/app_title,但無法解決。 – dannyroa

1

treesAreEverywhere的答案(以及用戶名)是正確的。但是瞭解Android Studio將極大地簡化創建構建風格或屬性特定資源文件的過程,這也非常有價值。

在AS項目窗口中,右鍵單擊res/values文件夾並選擇New> Values resource file。然後命名它(例如,「字符串」),如果不是默認值,則選擇源集合,並且選擇任何期望的限定符(例如,,屏幕寬度= 800)。這是確保您將資源覆蓋放在編譯器所需的地方的最簡單方法。

0

這就是我在我的項目中所做的。我創建了多種構建類型而不是口味。此解決方案將根據您嘗試組裝的構建類型爲您的軟件包名稱添加一個前綴。例如,對於開發包,軟件包名稱將爲com.sample.myapp.dev,同樣對於測試版軟件包名稱將更改爲com.sample.myapp.release。你可以調整它以獲得免費和付費前綴。希望它會有所幫助。

buildTypes { 
    release { 
     minifyEnabled false 
     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     signingConfig signingConfigs.production 
     applicationIdSuffix '.release' 
     versionNameSuffix '-RELEASE' 
    } 

    dev { 
     signingConfig signingConfigs.debug 
     applicationIdSuffix '.dev' 
     versionNameSuffix '-DEV' 
    } 

    beta { 
     signingConfig signingConfigs.debug 
     applicationIdSuffix '.beta' 
     versionNameSuffix '-BETA' 
    } 

    debug { 
     signingConfig signingConfigs.debug 
     applicationIdSuffix '.debug' 
     versionNameSuffix '-DEBUG' 
     debuggable true 
    } 
} 
4

接受的答案不適用於更新版本的Gradle。 您需要更換buildConfigbuildConfigField得到相同的結果:

productFlavors { 
free { 
    packageName "com.company.appfree" 
    buildConfigField "com.company.common.MonetizationType", "MONETIZATION_TYPE", "company.common.MonetizationType.FREE" 
} 

paid { 
    packageName "com.company.apppaid" 
    buildConfigField "com.company.common.MonetizationType", "MONETIZATION_TYPE", "company.common.MonetizationType.PAID" 
} 

}

相關問題