【问题标题】:Build android with gradle, replace string each product flavor用 gradle 构建 android,替换每个产品风味的字符串
【发布时间】:2013-10-18 05:32:35
【问题描述】:

在我为两个不同的应用程序构建 android 项目之前付费和免费。

我更改了每个值和字符串,所以昨天我犯了一个大错误。

所以,我正在学习如何使用 gradle 来构建我的应用程序。

我的应用有一些不同之处。

  1. 应用名称(只需添加后缀'-Free')-> values/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
    }
}

但是,构建的应用完全没有改变。

我错过了什么?

【问题讨论】:

    标签: android gradle


    【解决方案1】:

    查看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;"
        }
    }
    

    这个例子使用了一个枚举(你需要在你的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 一样),但只有一个字符串:您希望根据风格不同的字符串。 (您不需要在 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>
    

    您可能能够以不同的方式覆盖字符串,但为了清楚起见,我希望将被覆盖的字符串与其他字符串分开。

    【讨论】:

    • 谢谢!现在我可以使用不同的货币化类型进行构建。但我无法更改我的应用名称。我的项目结构不一样。在我的项目中,/src/my/app/**/*.java, /res/values/string.xml。那是Maven项目结构吗?我可以改变项目结构吗?
    • 我的项目结构是新的Android Studio / Gradle项目结构。请参阅文档tools.android.com/tech-docs/new-build-system/…。它应该解释一切。是的,您可能需要更改您的文件夹,但这样做并不难。为 android studio 创建一个新的示例项目并查看 build.gradle 文件和目录的设置方式。然后更改您的项目以反映该结构。
    • 如何在 AndroidManifest.xml 中引用 app_title?我试过@apptitle/app_title 但无法解决。
    • 类似:android:label="@string/app_title" 应该可以工作。
    • Gradle 2.14 无法识别 buildConfig 函数。仅限buildConfigField
    【解决方案2】:

    treesAreEverywhere 的答案(以及用户名)是正确的。但知道 Android Studio 将大大简化创建构建风格或属性特定资源文件的过程也是非常有价值的。

    在 AS 项目窗口中,右键单击 res/values 文件夹并选择 New > Values 资源文件。然后命名它(例如,“字符串”),如果不是默认值,则选择源集,并选择任何所需的限定符(例如,屏幕宽度 = 800)。这是确保将资源覆盖放在编译器需要的位置的最简单方法。

    【讨论】:

      【解决方案3】:

      这就是我在项目中的做法。我创建了多种构建类型而不是风格。此解决方案将根据您尝试组装的构建类型为您的包名称添加前缀。例如,对于 dev 包名称将是 com.sample.myapp.dev,同样对于 beta 包名称将更改为 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。 您需要将buildConfig 替换为buildConfigField 以获得相同的结果:

        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"
        }
        

        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-09
          • 1970-01-01
          • 1970-01-01
          • 2013-06-07
          • 2016-04-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多