Custom old Android project structure in Gradle - android

We have a project structure of the form
srcsrc_flavor1src_flavor2resres_flavor1res_flavor2
The core logic and resources are placed in src and res folder resp. The flavoured folders only contains few files which separate the two flavors.
Im trying to define this project structure withing the build.gradle file but havnt found any success. Also Im trying to use the prductFlavor tags to create simultaneous builds of the two flavors but no success. Doing all this within the Android Studio latest build

Assuming you have define your flavors like this:
productFlavors {
flavor1 {
...
}
flavor2 {
...
}
}
You can modify the sourceSets of each flavor
android.sourceSets.flavor1 {
java.srcDirs = ['src_flavor1']
resources.srcDir = ['res_flavor1']
}
android.sourceSets.flavor2 {
java.srcDirs = ['src_flavor2']
resources.srcDir = ['res_flavor2']
}
I hope this help... (don't hesitate to add more details about your problems since it will help us to help you)
Last remark: according my experience, Android-Studio is not very stable yet and not full-featured yet regarding gradle<-->IDE sync. So I strongly suggest you to always test your gradle scripts from the command line.

Related

SharedTest got warning "Duplicate content root detected" on Android Studio Chipmunk

After upgrade to Android Studio Chipmunk, my test failed because I can't access file inside shared folder that defined in build.gradle like this.
sourceSets {
androidTest.java.srcDirs += "src/sharedTest/java"
test.java.srcDirs += "src/sharedTest/java" }
It show warning pop up with message "Duplicate content root detected". Path [sharedTest] of module [unitTest] was removed from modules [androidTest]. Anyone can resolve this?
According to https://issuetracker.google.com/issues/232007221 ("Duplicate content roots detected" with Android Gradle plugin 7.2.0) Google no longer supports this construct in Android Studio Chipmunk 2021.2.1.
https://issuetracker.google.com/issues/232007221#comment17 says "Source sets can no longer contain shared roots as this is impossible to represent in the IDE."
To follow the on-going discussions, subscribe to
https://issuetracker.google.com/232007221 and
https://issuetracker.google.com/232420188
https://issuetracker.google.com/issues/232420188#comment19
The current recommendation is to use a separate com.android.library Gradle project to store any shared code required across test and androidTest.
According to (#kreker thx for the hint): https://issuetracker.google.com/issues/232420188#comment19
The current recommendation is to use a separate com.android.library Gradle project to store any shared code required across test and androidTest.
But often (at least for me) it is enough just to create a separate java project, move the shared test code into this new project and create two additional testImplementation and androidTestImplementation project dependencies to the new shared project.
Step-by-step (maybe it helps) I did it as follows: 1. next to the app folder create a new folder called sharedTest (or something similar). 2. create the sub-directories sharedTest/src/main. 3. Move (or rather git mv in order not to loose the version history) the shared test code: git mv app/src/sharedTest/java sharedTest/src/main/ (and do not forget to check-in). 3. in sharedTest create a new (minimal) sharedTest/build.gradle.kts file:
plugins {
java
}
dependencies {
}
java {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
4.Edit the settings.gradle.kts file and add the new shared project: include(":sharedTest"). 5. Edit the app/build.gradle.kts file: remove the conflicting shared source-set section android{...} and add 2 new dependencies:
dependencies {
//Share Code between androidTest and test
//https://stackoverflow.com/questions/72358843/sharedtest-got-warning-duplicate-content-root-detected-on-android-studio-chipm
testImplementation(project(path = ":sharedTest"))
androidTestImplementation(project(path = ":sharedTest"))
}

Product Flavor structure

I have a project that uses ~30 product flavors. Apart from the "main" code, the flavors don't have much to them, just some unique resources. Since there are so many, I would like to structure my code directories like this to make it more organized:
src
main
java
res
productFlavors
flavor1
java
res
But the build doesn't recognize the flavors when they are on a different level than the "main" folder. Is there any way I can make this work?
I have a project that uses ~30 product flavors
One more, and you'll match Baskin-Robbins' original ~31 flavors.
But the build doesn't recognize the flavors when they are on a different level than the "main" folder. Is there any way I can make this work?
You can override where source comes from in your module's build.gradle file. While I haven't tried it for your scenario (only for building Eclipse-style projects using Gradle), something like this should work:
android {
// lots of cool stuff here
sourceSets {
flavor1 {
manifest.srcFile 'src/productFlavors/flavor1/AndroidManifest.xml'
java.srcDirs = ['src/productFlavors/flavor1/java']
aidl.srcDirs = ['src/productFlavors/flavor1/aidl']
res.srcDirs = ['src/productFlavors/flavor1/res']
assets.srcDirs = ['src/productFlavors/flavor1/assets']
}
// lather, rinse, repeat
}
}
If you stick to the fixed pattern of src/productFlavors/.../ (where ... is the flavor name), you can probably use a bit of Groovy scripting to iterate over an array of flavor names and wire up the sourcesets accordingly.

How to add a new source directory to an Android Studio project?

So ultimately I'm trying to separate my integration tests from the unit tests in an Android Studio project. I've found a few resources on the subject:
http://selimober.com/blog/2014/01/24/separate-unit-and-integration-tests-using-gradle/
https://blog.safaribooksonline.com/2013/08/22/gradle-test-organization/
Separating integration tests from unit tests in Android Studio
All these seem to indicate that the way to go is to create a new sourceSet for the integration tests, and then to create a new test task which builds and runs the tests in that source set. I can't get past the first step of creating a source set which is recognized by Android Studio.
Here's what I have within app/build.gradle, which builds without errors, but does not result in an integrationTest source root I can add classes to:
android{
...
sourceSets{
integrationTest {
java.srcDir('src/integrationTest/java')
}
}
}
My questions are:
Where precisely do I have to add the sourceSets block? In build.gradle? in app/build.gradle? In app/build.gradle inside the android block?
Once I've added my source set in he right place using the correct syntax, is this sufficient for Android Studio to detect and present it in the UI along side the main and test sources, or are there additional steps?
edit:
I've attempted to follow the instructions in marius' answer, but integrationTest isn't showing up in my build variants. Here's what I'm seeing:
This is enough:
android{
...
productFlavors{
integrationTest {
}
}
}
Regarding your 1st question: The productFlavors block should be in your app/build.gradle, inside android block.
Regarding your 2nd question: Once you add this to your build.gradle file, you also need to create your folders /src/integrationTest and /src/integrationTest/java . Once that is done, sync your gradle files and choose your new Build Variant from the Build Variant window, in order for the IDE to detect it as the active source folder.

Gradle reference to external archive directly

How can we refer an archive file ( aar for android or jar in general) from the build.gradle.
eg : compile files('https://--artifactoryonline.com-url--Debug.aar')
Background/Root Cause :
Android Library project has multiple flavors to be supported.
productFlavors {
flavor1 {
// Add any falvor1 flavor specific details here
}
flavor2 {
// Add any flavor2 specific details here
}
}
While the flavors are working fine and aar is generated and uploaded to the articfactory, reference from the maven is not getting resolved as POM files are not generated for library flavors. which in turn leads to maven-metadata.xml not being updated.
This seems to be an issue - Reference :How to upload multiple android archives (one for each flavor)
So to circumvent the situation wanted to get the archive files as they are generated correctly.
Any help would be greatly appreciated!

Exclude a class from the build in Android Studio

I've been learning Android over the past few months and have been using Eclipse v4.2 (Juno) as my IDE.
I am trying to migrate to Android Studio. How can I exclude some of the classes from build path I have yet to complete?
In Eclipse, it was a straightforward right click. I can't find any reference to it in Android Studio.
AFAIK, IntelliJ allows to exclude packages. Open Project Structure (Ctrl + Alt + Shift + S in Linux) → Modules → Sources tab.
However, if you would like to exclude only one class, use the Gradle build file.
Android Studio uses Gradle, so in the build.gradle file, add a custom SourceSet inside the android configuration that excludes your class, e.g.:
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 19
targetSdkVersion 19
packageName "org.homelab.lab"
testPackageName "org.homelab.lab.test"
}
sourceSets {
main {
java {
exclude '**/SomeExcludedClass.java'
}
}
androidTest {
java {
exclude '**/TestSomeExcludedClass.java'
}
}
}
}
It works fine with Android Studio v3.0:
apply plugin: 'com.android.application'
android {
defaultConfig {...}
buildTypes {...}
sourceSets {
main {
java {
exclude 'com/example/full/package/path/MainActivity.java'
}
}
}
}
It can't be done.
Maybe it could back in May 2013 when the accepted answer was provided, but not anymore (as of Android Studio 1.2).
Here is the issue: Sourceset component should be more like the Java one
According to the labels they are targetting Android Studio 1.5 for adding these feature.
Cross posting from https://stackoverflow.com/a/69261642/3689782 but it seems useful to repeat here.
I came across a way to make this work specifically for Android unit tests (but I'm assuming it's adaptable) using a combination of other solutions from the link above:
def filesToExclude = [
'**/*TestOne*.kt',
'**/*TestTwo*.kt',
...
]
tasks.withType(org.gradle.api.tasks.SourceTask.class).configureEach {
it.exclude(filesToExclude)
}
android.sourceSets.test.kotlin.exclude(filesToExclude)
In my particular case, the extra wildcards around the test name were needed due to other generation occurring (specifically, Dagger with kapt).
This seems to be a bit hacky way to approach it, but it works by ensuring the test target is excluded from all tasks that it could actually be excluded from (including both build & kapt tasks). The sourceSets exclusion is still necessary for the file not to be picked up for compilation (I think this is the Kotlin Gradle Plugin doing it, but it might also be Android Gradle Plugin--I'm not well versed enough in debugging Gradle builds to pin it down).
The way I used to do the same was by,
For Windows: Right click on the Java file → Show in Explorer → change extension of the file from '.java' to '.c'.
For Mac: Right click on the Java file → Reveal in Finder → change the extension of the file from '.java' to '.c'
It is as simple as that.
For my case I need to prevent a whole folder then I did it by this -
sourceSets {
main {
jniLibs.srcDirs = ['libs']
java {
exclude 'com/example/myfolder'
/* The holder name I want to excludes its all classes */
}
}
}
Move it to a new folder.
Right-click → Show in explorer → cut and then paste to a new folder (outside of any project).
I just created a new folder inside of AndroidStudioProjects folder and placed them there.

Categories

Resources