20

Background

On Android Studio, you can have different build types, each has its own configuration, similar to product-flavors (as shown here)

The problem

I wish that each time I have my app installed somewhere, I would immediatly know which type it was - release or debug, just by looking at it.

For this, I think I can use the build.gradle file :

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        debuggable true
    }
}

Thing is, I don't know what to put there. I want the app name to be different (and yet have the string in the strings files, as it's translated), and I want to set the style of something in the app to be different (for example, the color of the action bar).

I've found that I can use "resValue" (found about it here), but for some reason, no matter what I do, it won't compile:

  • If the resource was already declared (like in the app-name, which is translated), it says the resource is duplicated
  • If the resource wasn't declared, I can't reach it via code/xml.

The question

How do I use different resource values for the build types, even if they already exist?

Community
  • 1
  • 1
android developer
  • 114,585
  • 152
  • 739
  • 1,270

2 Answers2

24

How do I use different resource values for the build types, even if they already exist?

They already exist in the main sourceset. Add other sourcesets for your other build types of interest, where you override the resources you want.

For example, in this sample project I have a main sourceset and a debug sourceset. Both have the app_name string resource in res/values/strings.xml, but with different values. In a debug build, the debug sourceset version of the resource will be used; in any other build (e.g., release), the debug sourceset is ignored entirely, and the main sourceset version of the resource is used.

Note that I do not have a release sourceset. Particularly when overriding resources, this is perfectly fine -- you only need a sourceset for a build type when you want to change something for that build type, not for every build type that you are using.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • So you mean I don't need to use "buildTypes" in the "build.gradle" file for this task, but just put the resource files in the folders of each build type ? In "src" folder, one on "main", and one on "debug" folders ? – android developer May 16 '15 at 18:47
  • @androiddeveloper: For the built-in build types of `debug` and `release`, yes. You are welcome to invent your own build types too, if needed, and for that you will need to use `build.gradle` (to define the types) in addition to sourcesets (for supplying alternative inputs to the build, like replacement versions of resources). – CommonsWare May 16 '15 at 18:49
  • I see. Even though I don't need it (well now, at least), would you please tell me how to set another folder for another build type that you create yourself? Also, does the same operation (of putting files into those folders) work for java files too (my guess is that it won't) ? – android developer May 16 '15 at 18:54
  • Also, what exactly does "resValue" used for? – android developer May 16 '15 at 19:11
  • @androiddeveloper: "would you please tell me how to set another folder for another build type that you create yourself?" -- see `mezzanine` in the `build.gradle` of the sample app I linked to. "does the same operation (of putting files into those folders) work for java files too" -- yes, except that you cannot replace Java classes defined in another sourceset (e.g., `main`). "what exactly does "resValue" used for?" -- it would be for cases where you wanted to define (not replace) the resource based on calculations made in `build.gradle`. – CommonsWare May 16 '15 at 19:27
  • About "mezzanine", I don't see a folder that was created for it, so maybe I wasn't clear enough: I meant how you prepare the folder for the new build type? About Java, this was what I thought- overriding of classes (exact class-path) isn't possible. Makes sense. About "resValue", this seems like a rare thing to do, maybe for version code (like one that's based on the current time) ? – android developer May 16 '15 at 19:42
  • @androiddeveloper: "I meant how you prepare the folder for the new build type?" -- um, `mkdir`? I mean, you create a directory named `mezzanine` the same way that you create a directory named `debug`. The only difference is that you have to tell *Gradle* about the existence of `mezzanine`, which is done in `build.gradle`. "this seems like a rare thing to do" -- agreed. – CommonsWare May 16 '15 at 19:50
  • About "mezzanine", ok, I thought you need to specify it in the build.gradle file, as the others were the default ones (there isn't a folder called "release", for example). – android developer May 16 '15 at 20:06
  • @androiddeveloper: And you do, as I indicated [here](http://stackoverflow.com/questions/30279304/how-to-use-build-types-debug-vs-release-to-set-different-styles-and-app-names/30279350?noredirect=1#comment48657206_30279350) and [here](http://stackoverflow.com/questions/30279304/how-to-use-build-types-debug-vs-release-to-set-different-styles-and-app-names/30279350?noredirect=1#comment48658330_30279350). Quoting the earlier comment, "You are welcome to invent your own build types too, if needed, and for that you will need to use `build.gradle` (to define the types) in addition to sourcesets..." – CommonsWare May 16 '15 at 20:08
  • ok, sorry. probably missed the part that the additional folders are called "sourcesets" (right?). – android developer May 16 '15 at 20:37
  • @androiddeveloper: In the original discussion, `main` and `debug` are called sourcesets. That's Gradle's term (though I think Maven might use it too for their build system). – CommonsWare May 16 '15 at 20:42
  • Thank you again. I've now ticked your answer. You are great and have a good patience ! – android developer May 16 '15 at 20:46
  • I think Android-Studio has a bug with this feature. At first it worked as expected, but when I changed the values (of a single boolean resource) and then back, it acts as if debug build is like release build. Will have to check it further and maybe create a POC. May I show you this issue in case I can reproduce it ? – android developer May 17 '15 at 05:27
  • 2
    @androiddeveloper: If you file an issue for it on http://b.android.com, consider linking to it here. – CommonsWare May 17 '15 at 10:33
  • Can't reproduce on POC. Maybe I just did something wrong. Anyway, thank you. – android developer May 17 '15 at 22:12
  • I have set my URL in the build file for the debug build type, is it possible to reverse engineer the build file somehow and expose my URL which is not what I want or does my URL which is defined in debug build type be exposed if I upload the release apk to playstore. – Aman Verma Nov 10 '18 at 11:00
  • 1
    @AmanVerma: "does my URL which is defined in debug build type be exposed if I upload the release apk to playstore." -- if you have done this correctly, that URL will not exist in the release APK. – CommonsWare Nov 10 '18 at 11:36
  • debug { debuggable true applicationIdSuffix ".debug" resValue "string", "BASE_URL", '"Mytesting URL"' resValue "string", "app_name", "UAT APP" } – Aman Verma Nov 10 '18 at 11:58
  • 1
    @AmanVerma: That URL should not exist in a `release` APK, if this is the only place that you have defined that URL. – CommonsWare Nov 10 '18 at 11:59
  • Yeah. This is the only place where i have set the URL. However if i search this particular URL i find it in one more place which is debug\..\generated. I think it is auto generated and will not be visible in release APK or is it? – Aman Verma Nov 10 '18 at 12:01
  • 1
    @AmanVerma: The contents of a `debug` directory under the `build` directory are not included in a `release` APK. If you have additional concerns, please ask a separate Stack Overflow question. – CommonsWare Nov 10 '18 at 12:03
  • @CommonsWare i have already asked this question but no one replied...this is the link... https://stackoverflow.com/questions/53232057/can-build-types-resources-be-visible-while-reverse-engineering-the-app – Aman Verma Nov 10 '18 at 12:05
-2

In File|Project Structure|app|Flavors we have:

Version Name: 1.3

In Strings resource file we have:

<string name="app_name">MyAppTitle</string>

In "onCreate" of MainActivity class:

...
//add version to application title
int versionCode = BuildConfig.VERSION_CODE; // unused in my application
String versionName = BuildConfig.VERSION_NAME;
this.setTitle(this.getTitle() + " v"+  versionName);
...

The result is "MyAppTitle v1.3"

Piero
  • 5
  • 2