用gradle构建android,替换每个产品的字符串味道

时间:2013-10-10 12:43:19

标签: android gradle

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

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

所以,我是如何使用gradle构建我的应用程序的。

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

  1. 应用名称(只需添加后缀' -Free') - > values / string.xml

  2. 更改我的* .java

  3. 中的标记

    // signedConfigs被忽略。

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

    但是,构建的app根本没有改变。

    我错过了什么?

4 个答案:

答案 0 :(得分: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;"
    }
}

此示例使用枚举(您需要在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>

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

答案 1 :(得分:5)

接受的答案不适用于较新版本的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"
}

}

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

这就是我在项目中的表现。我创建了多种构建类型而不是flavor。此解决方案将根据您尝试组装的构建类型为您的包名添加前缀。例如,对于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
    }
}