Defining 'resValue' using an existing string definition
Asked Answered
N

4

21

I'm interested in defining my many flavors of my apps more so in the strings.xml files rather than the build.gradle. Given multiple flavors, I'd like a simplified release/debug variant:

  buildTypes {
    release {
        signingConfig signingConfigs.release
        resValue "string", "app_name", "@string/prod_name"
    }
    debug {
        applicationIdSuffix ".beta"
        resValue "string", "app_name", "@string/beta_name"
    }

Then in each of my build flavors' custom res/values/strings.xml files, I would define each their own "prod_name" and "beta_name". I also want to use this similar framework for defining providers' authorities etc...

This currently will build fine via gradle command-line, but fails to be recognized by Android Studio.

Android Studio Error:

I find this within 'generated.xml'

<!-- Values from build type: debug -->
<string name="app_name">@string/beta_name</string>

Which is typical of how one string references another. But this time Android Studio gives me this error:

Error:(7, 29) No resource found that matches the given name 
(at 'app_name' with value '@string/beta_name').

I'm using Android Studio 2.1 Preview 5

Nacred answered 4/4, 2016 at 23:25 Comment(2)
Could you be more specific about what exactly "fails to be recognized by Android Studio" means?Toothwort
..w.hy don't you just put the right strings into the right resource directories? src/release/res/values/strings.xml for release specific strings, src/debug/res/values/strings.xml for debug builds?Lunde
A
14

In my experience you can't resolve a @string/my_string in the resValue DSL. Gradle put the value as a simple string inside the resource file.

In this case you can use different folder to achieve it:

Just use:

src/release/res/values/strings.xml
src/debug/res/values/strings.xml

If you would like to use different resource for each build variant (build type+flavor) you can use:

src/flavor1Release/res/values/strings.xml
src/flavor1Debug/res/values/strings.xml
src/flavor2Release/res/values/strings.xml
src/flavor2Debug/res/values/strings.xml
Assert answered 5/4, 2016 at 6:41 Comment(4)
What if I'm already dealing with multiple flavors? I have my regular "res" directory, as well as my flavor res directories: "/one/res/", "/two/res" etc... I was originally trying to just define "prod_name" and "beta_name" in each flavor's res subdirectory, thus minimizing a further factor of 2 multiplication of directories...Nacred
In this case just add only the strings (which have different values in the buildtype) in these files.Assert
Can't find a great example in the documentation. How do I go about defining the debug and release directories for each flavor. I already have my main "res" as well as "one/res", "two/res", etc... for all of the flavors.Nacred
How is this different than using Gradle's resValues?Subtreasury
S
19

This is actually possible. All you have to do is declare those strings as empty in your defaultConfig, like this:

defaultConfig {
    resValue "string", "prod_name", ""
    resValue "string", "beta_name", ""
}
Sharanshard answered 6/2, 2017 at 14:56 Comment(3)
And this won't conflict with the definitions in each flavor's strings.xml files? The flavor's strings.xml file overrides gradle's 'defaultConfig'?Nacred
Note that this seems to be required since updating to Gradle plugin v3.5.0Am
This seems not to work anymore. I used it this way too in the past (when you wrote this answer)Distinct
A
14

In my experience you can't resolve a @string/my_string in the resValue DSL. Gradle put the value as a simple string inside the resource file.

In this case you can use different folder to achieve it:

Just use:

src/release/res/values/strings.xml
src/debug/res/values/strings.xml

If you would like to use different resource for each build variant (build type+flavor) you can use:

src/flavor1Release/res/values/strings.xml
src/flavor1Debug/res/values/strings.xml
src/flavor2Release/res/values/strings.xml
src/flavor2Debug/res/values/strings.xml
Assert answered 5/4, 2016 at 6:41 Comment(4)
What if I'm already dealing with multiple flavors? I have my regular "res" directory, as well as my flavor res directories: "/one/res/", "/two/res" etc... I was originally trying to just define "prod_name" and "beta_name" in each flavor's res subdirectory, thus minimizing a further factor of 2 multiplication of directories...Nacred
In this case just add only the strings (which have different values in the buildtype) in these files.Assert
Can't find a great example in the documentation. How do I go about defining the debug and release directories for each flavor. I already have my main "res" as well as "one/res", "two/res", etc... for all of the flavors.Nacred
How is this different than using Gradle's resValues?Subtreasury
G
4

It is possible you can add res values inside the gradle for your build flavors

productFlavors {

   prod {
        dimension "default"
        resValue "string", "app_name", "your prod app name"    
    }


    staging {
       dimension "default"
        resValue "string", "app_name", "your staging app name"    

    }
}
Gwalior answered 16/12, 2019 at 10:0 Comment(1)
The original aim was to keep all definitions in the various strings.xml files rather than having definitions being set in the gradle file directly.Nacred
K
0

I'm using a little bit another approach.

Replace android:label in your AndroidManifest:

 android:label="${appName}"

Paste this in your build,gradle - buildTypes - your env

Example:

buildTypes {
  create("staging") {
     ,,,
     manifestPlaceholders["appName"] = "*Your App Name* Staging"
  }
}
Koine answered 23/4 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.