Is it possible to have an Application subclass that's used only for tests when building with gradle? I've done something like this in the past before the gradle build system, but I can't find a way to do so now. The problem seems to be that it's impossible to customize the AndroidManifest.xml used for the instrumentation test APK.
You can create build variants which would at let you have a different version of the Application class and let you override the manifest. You could then test only that specific variant. http://tulipemoutarde.be/2013/10/06/gradle-build-variants-for-your-android-project.html
http://tools.android.com/tech-docs/new-build-system/user-guide
"For instance, if the flavors are used to generate a ads-based app and a paid app, one of the flavors could have a dependency on an Ads SDK, while the other does not.
dependencies {
flavor1Compile "..."
}
In this particular case, the file src/flavor1/AndroidManifest.xml would probably need to include the internet permission."
Related
Short question:
How can I change the package name for debug or release build type in a library module?
Context:
In an Android project with MVP + Clean architecture, we have the repository pattern in a library module. We want to include Firebase on that library with two environments (development and production).
I already created the project in Firebase (com.example.com and com.example.com.dev) and then downloaded the respective google-services.json to src/main and src/debug folders.
Gradle google-services plugin validates the module package name with the client ID defined in the google-services.json, but Android restrict to change the applicationId in a library (I can't find the technical reason why)
Things that I tried:
Have two AndroidManifest.xml with different package property. com.example.com in the src/main and com.example.com.dev in src/debug/ but the second one it is just ignored
Set manifest.srcFile in Gradle sourceSets. The file is in the list when I run ./gradlew sourceSets but the package name doesn't change
Two different flavors in the library module and set different manifests for each one. The package anyway doesn't change.
At this moment I have just two suitable solutions:
1. Keep the Firebase setup and implementation in the app module outside of the repository.
2. Have only one environment for Firebase.
Thanks a lot for any help or advice.
EDIT:
Consider that I need to modify the package in a module (library), not in the app. For some weird reason Gradle shows this error when I try to use applicationIdSuffix or applicationId in a module:
ERROR: Library projects cannot set applicationIdSuffix.
Library projects cannot set applicationId.
This is the designed behaviour of Android Library project.
Two different flavors in the library module and set different
manifests for each one. The package anyway doesn't change.
Probably you need to change your Build Variants to that particular flavor/buildtype then you can see the updated package name taking effect.
See below screenshot.
I spent some time investigating and trying different alternatives to achieve two different package name per flavor or build type in a library module, and my short answer is: You can't, at least without doing something tricky and dirty.
Some guys that recommend using the parameter applicationIdSuffix or applicationId, that option doesn't work because of the design of library modules restricts those parameters to the app module. In a library, the package must be defined in the manifest.
That restriction delimits options to flavors, but, the package attribute in the manifest isn't merged, and you get an error when having different package name for the scr/main/AndroidManifest.xml and src/flavor/AndroidManifest.xml.
A tricky solution is to get the currently selected flavor form the task name and then change the main manifest in the sourceSets.
sourceSets {
main {
manifest.srcFile "src/$flavor_name/AndroidManifest.xml"
}
}
This hack works but in general is a bad idea, and I prefer to change the design of my architecture and implement the repository for both Firebase variants in a different way.
Gradle plugin: 3.2.0
I have an application with three different flavours and two build types. The main module defines some common interfaces and each flavour implements them. The flavours correspond to stores : google, amazon and samsung. The app proposes some in-app purchases, which is specific to each flavour.
I implemented a few debug classes to ease the integration tests of the google the flavour. The debug classes implement the IInAppBillingService and an alternative to the purchase dialog. Now the problem is that some debug classes have dependencies on a flavour. I can't switch to another flavour without having compilation errors.
I would like to keep these test classes, as they are used in integration tests. Also, they should be kept away from the release build type, to avoid any debug/testing code appearing in the released version.
My question is : how to define classes with dependencies on a flavour, but that are not used during the building of the release version ?
As you probably know, you can put code and assets specific to a flavor in its own folder under src. For example you can have folders such as google, amazon, and samsung for each flavor. You can also create debug and release folders for classes and assets specific to each build type. This is useful if you have code only used for development but that should not go into the final release version.
You can take this a step further and create folders for any combination of build type and flavor, for example, googleDebug or amazonRelease.
For automated testing, create a test folder for unit tests which run locally on you development machine or an androidTest folder for instrumented tests run on a device or emulator. These can also be combined with build types and flavors, for example androidTestDebug, androidTestSamsung, or androidTestSamsungDebug.
All classes for testing should go under
Instead of having the classes that handles the billing logic in the flavour folder directly, I used another module specific to a flavour.
In the google billing module, I keep all the classes involved in the in-app purchases. Each module specific to a flavour is imported for the corresponding flavour. This way, I avoid mixing code specific to different flavours.
For example, in the build.gradle file I have :
googleCompile project(path: ':inappbilling_google')
In the inappbilling_google module, I have all the classes involved in in-app purchase through Google in-app billing. There is a debug folder to keep all the classes that should not appear during the release build process.
I was quite happy with this solution, as I keep clearly separate the code of the different flavours and build types... until I discovered that Gradle had some limitations. Indeed, the code present in the debug folder of modules is not included during the compilation. This is a known issue (limitation) of Gradle and the Android Gradle plugin.
However, the Google team and Gradle team have worked on this and have announced a solution to this, with the version 2.5 of the Android Gradle plugin.
In a near future, it will be possible to separate our code using the Android Gradle plugin only. Good news !
I have an old maven project which I'm trying to migrate over to gradle for practice. It uses a configurations.properties file to configure different apks. For example, I would use it set a boolean for the target marketplace, and would do this from the command line like so:
mvn install -DexampleFlag=true
There are a few of these flags, and they are used at various points throughout the app. Is there a way to create this file using gradle?
Or, of course, if you have a better solution I'd be happy to hear that too.
EDIT
Okay, so I've got flavors, and I'm adding values to fields in the generated BuildConfig class like so:
android {
flavor1 {
buildConfigField 'boolean', 'EXAMPLE_FLAG', 'true'
}
}
And that works for the main app subproject. However, I also have an api subproject which needs to be able to access the flags too - which it can't, as the app subproject is the one with the flavors. If it helps, the api subproject is a dependency of app.
Any help here is appreciated.
Usually, this wouldn't be managed using flags but by defining multiple application flavors. For more information on flavors, see the Android Gradle plugin docs.
I've added several dependencies in my Android project in IntelliJ, for unit-tests (JUnit4, JMock, SQLite-jdbc, etc.). I defined all of them as "test" scope in the module dependencies settings, so that they are used only when running my unt-tests and they don't get in the way of the production code.
My problem is that when the .apk file is generated, it basically ignores the "test" scope setting, and includes all the unneeded dependencies, which boost the size of the .apk by a dozen MBs.
Is there a way to prevent this from happening?
Android tests can run on device, therefore test dependencies may be required to actually run them. If classes that you are using in the tests are already available on the device as a part of Android platform, you can try setting the scope to Provided.
While continuing to develop my application and test it on a real phone, I need to have the release version of it on the same phone, for demonstration purposes (the release version is much more responsive, thanks to no-logs).
The problem is that the only way to make two applications co-exist on the same device in Android is by having different package names.
But package names require re-factoring and lots of propagating manual fixes... not to mention that this confuses version control...
Ideally, Eclipse+ADT would allow appending a modifier variable that would automatically generate a different package name for debug/release and would allow such co-existence, but I couldn't find any mechanism that allows doing that.
Do you know of any way to workaround this?
Creative solutions and ideas are welcome.
Use Android Studio because gradle make your life a lot easier - just use applicationIdSuffix
android {
...
buildTypes {
release {...}
debug {
applicationIdSuffix '.debug'
}
}
}
For more go here.
The only way I know is to change the package name in your applications manifest file. Eclipse should handle all the code renaming for you.
Could you put all your code in a Library Project and then just have two normal projects,
that have different package names and just include the library project in both?
This should keep all your code in one place.
The normal projects would most likely only need a valid manifest file that points to the
activities in the library project.
You may want to try this technique using ant, Jenkins and perhaps other tools to automate package renames as suggested by #LAS_VEGAS.
Although not what you asked for, this cool code snippet can help you find out at runtime whether your code is debug or release.
Another interesting such attempt can be found in this thread. I am not sure though if it works on Android.
In Android Studio, Adding build variants using Product Flavours which can be easily customized for various environments and to test side by side multiple app variants of same app. Check out this link for more information - Configuring Gradle