Is it possible to use a Gradle Rule (Or more than a single one) to replace values in resources?
I'm aware that this is something that flavors would do well but I need to have lots of values that must be changed as a build configuration and i though that Gradle rules would solve this issue.
You cannot modify the contents of resources readily through anything currently in Gradle for Android.
You can use product flavors or build types to replace resources by means of having the replacement resources in the appropriate sourceset (e.g., in src/debug/ for the debug build type).
You are also welcome to attempt to write a Gradle plugin or otherwise create a Gradle task that you insert into the build sequence that modifies some intermediates copy of the resources and ensures that this copy is what is included in the actual build.
Related
UPDATE: Sorry for disturbing anyone, I found the answer myself. I had a disableCrashlytics attribute in my build.gradle for the concrete buikld types, what prevented appropriate gradle task from being generated.
Sorry for confusion. I'll leave this here maybe will help someone else :)
I have a project with multiple flavors and build types. I want to distribute my Beta build with crashlytics (using gradle distribution).
In gradle I can execute task like this
crashlyticsUploadDistribution<FLAVOR_NAME>Release
But I am not able to distribute apks with any build type except of Release and Debug.
For example, I have customBuildType in my project, and I want to execute
crashlyticsUploadDistribution<FLAVOR_NAME><BUILD_TYPE_NAME>
such tasks, unfortunately, do not exist.
How can I build custom build types apks for the distribution in this case?
P.S. Build types are different, but the applicationId is the same, since I don't need to make them different.
I have different configurations for my Android project (e.g. google, amazon). Gradle allows generating BuildConfig parameters, that can be checked at runtime, but this isn't what I am really after. I want to have a particular code (method, class, etc) to be present or absent (not just bypassed) in the project, depending on configuration.
This is how I implement that in Eclipse. I have a folder in an Eclipse project (named e.g. platform-specific), not included in BuildPath as well as several Ant scripts (make-google, make-amazon), that copy relevant files from platform-specific folder to src folder and delete irrelevant files from src folder.
Since Eclipse provides an Ant window to view all scripts, I can run a particular script and reconfigure the project to suit chosen configuration.
Is there a way to do that in Android Studio? I know that Gradle allows running and even importing an Ant script, but it isn't a convenient as with 'true' Ant, and I can't find a way to choose a script to run. Maybe Gradle provides its own way to do that?
For two flavours it will work, but if I have say 3 flavours, module 1 appears in flavours 1 and 2, module 2 in flavours 1 and 3, will it mean replicating those modules in each folder? So, every time I modify a code a such a module, I need to replicate the modification in another folder.
Not if you organize your code.
You appear to be using "modules" generically. Android Studio has a specific definition of that term (what Gradle refers to as sub-projects). And you can leverage those to help your cause.
Suppose that you create google, amazon, and yandex product flavors. Then:
Any code that is common to all three goes in src/main/.
Any code that is unique to a single flavor goes in that flavor's source set (e.g., src/yandex/).
Any code that is shared by two flavors goes into a library module that is added to the appropriate flavors using flavor-specific dependencies (e.g., yandexCompile and amazonCompile).
In all cases, there is one copy of your code. Whether it can go in the application module (e.g., app/) or goes into a library module depends on which flavors need that code. For a scenario like this, dependency injection will help you manage what code then gets wired together for each flavor.
I have an Android application project that depends on two Android libraries. The two Android libraries specify two resources with the same resource ID. In the old Ant build system, the priority of libraries was specified in a project.properties file, but such a file is not used in the Gradle build system.
Although the Resource Merging doc explains the priorities and merge process for resources that conflict between build types, product flavors, application projects, and library projects, it does not explain what occurs when two libraries (who have no common dependencies) are merged in a single project. During the merge process of the build process, how does the Android Gradle plugin determine which library's resource has a higher priority?
There is not a way to specify a priority for the library's resources.
You can only setup the prefix in your library with
android {
resourcePrefix 'mylib_'
}
Ah, looks like the Android developers documentation finally has an answer for us. I pulled this from https://developer.android.com/studio/projects/android-library#Considerations:
The build tools merge resources from a library module with those of a dependent app module. If a given resource ID is defined in both modules, the resource from the app is used.
If conflicts occur between multiple AAR libraries, then the resource from the library listed first in the dependencies list (toward the top of the dependencies block) is used.
To avoid resource conflicts for common resource IDs, consider using a prefix or other consistent naming scheme that is unique to the module (or is unique across all project modules).
I bolded the relevant paragraph. It looks like that the order in which dependencies can appear in a Gradle dependencies block can affect the build process! This is a small thing to be wary of.
#Angela answer is great for solving your (and actually my) problem, for answering your problem according to how Android choose the right resource and what exactly the priority:
From the resource merging part in the build process:
The priority order is the following:
BuildType -> Flavor -> main -> Dependencies.
...
This means that if src/main/res has
res/layout/foo.xml
res/layout-land/foo.xml
and src/debug/res has
res/layout/foo.xml
Then the merged resource folder will contain the default foo.xml from
src/debug/res but the landscape version from src/main/res
In iOS do we have something like Gradle Build Flavors on Android.
Basically I want to integrate Applause SDK with my app but I dont want that code to be part of the release build. I only want to use applause sdk only to distribute the app internally and for bug reporting.
If there is nothing like flavors then what is the best way to do this.
You can make use of Schemes and Build configurations in Xcode. Here's the official documentation: https://developer.apple.com/library/ios/recipes/xcode_help-project_editor/Articles/BasingBuildConfigurationsonConfigurationFiles.html
After you create a build configuration, you should edit your scheme to use that build configuration. For that click on your scheme and select Edit Scheme.
In short, the process is:
Create a build configuration
Set some custom flags for that configuration. For this, go to your target, select Build Settings tab, and search for Preprocessor Macros. There you'll be able to add custom flags
Edit your scheme, or create a new scheme, to use your build configuration.
In your code, you'll have to ask if the flag is available using preprocessor macros:
#ifdef APP_STORE
//do something
#endif
There are several approaches you can take to build an iOS app in different flavors:
Different versions of a resource file
Use a custom build variable to switch between different versions of a resource file. This article discusses how to build an app with different icons.
For *.strings files and resources linked in *.storyboard files the suffixing approach suggested in the first item did not work for me. So I added a Run Script build phase early in the pipeline. Using a script you are free to do whatever you want before the usual build chain handles your files. This is great for dynamic file generation or advanced file selection logic. As a switch you can (again) use a custom build variable.
Modifiying code
Use a compiler flag as suggested here. These can be checked using the preprocessor.
Alternatively you can (again) check custom build variables. To make them accessible add them as a key in a plist file.
I have a library project that serves as the backend for a number of other projects. It does the web connection and parsing etc. Then I have other front end projects that build on this.
For development and server environments I wrote an ANT build script that replaces certain values in the code bases on the build type.
So I have two targets buildDev and buildProd.
Is there a way for me to have the values set correctly while building the dependent (non-library projects). E.g. if I do ant debug on the project it builds the backend with ant buildDev and if I do ant release it does it with ant buildProd.
I'm pretty sure that's not possible, so what are the alternatives.
For the curious, the custom builds just replaces a file that has static variables that are assigned different values based on the type of build. Nothing too complex.
In ant, there are a variety of different tasks that can be used to edit properties in a file.
I'm sure you're aware of property files, so if you use the documentation here:
http://ant.apache.org/manual/index.html
It could probably help you.
If you set your variables in an ant-style property file, then for certain builds you could have separate files for separate builds, and then therefore have the variables set correctly.
If you're talking about having variables set in your source, try the copy task:
http://ant.apache.org/manual/index.html
Filterchains on a copy task will allow you to replace certain lines of code out of a file. So if you have a variable named server_ip or something like that, you can use a filterchain to change that value and re-copy that source file back into your tree.
I hope this answers your questions. If not, be gentle. I'm kinda new at answering stuff and I got slightly chewed out on an Android post haha.
I found the solution. The default Android Ant build.xml passes the release name to the child library project script while calling it. The following lines and the code that follows details it.
<!-- figure out which target must be used to build the library projects.
If emma is enabled, then use 'instrument' otherwise, use 'debug' -->
<condition property="project.libraries.target" value="instrument" else="${build.target}">
<istrue value="${build.is.instrumented}" />
</condition>
Then it's just a matter of having the same targets in all the interdependent projects.