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.
Related
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"))
}
I'm trying to use Android Studio 1.3.1 to compile an NDK project using the experimental gradle syntax.
My build.gradle looks very much like the one from the Teapot example
With the exception that my source tree has some files which I don't want to include in the build. I can't remove these files so I need gradle to ignore them.
I tried adding an exclude definition:
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
excludes += "src/main/jni/FileToExclude.cpp"
}
}
}
}
but that did not affect the outcome. gradle still tries to compile this file.
I tried excludes, exclude with =, += and with nothing at all but no permutation works.
From what I've found, the correct directive to exclude the file from the build is exclude, not excludes. Check your build.gradle to make sure you didn't make a mistake here (you've used excludes in the provided sample).
Upd: ok, after some research I found this thread on the AOSP issue tracker. The topic starter says the following:
The java/resources components of the sourcesets allow for include/exclude patterns.
We should do this for aidl/rs/jni/assets.
The issue is still open so I suppose this functionality has to be implemented in the Android Gradle plugin or Android Studio or in both of them (and isn't implemented yet). It'll be implemented in Android Studio 1.5, at least this is what the tags are saying.
I think you are giving path of the file in wrong manner.
It should be:
srcDir 'src/main/jni'
exclude 'FileToExclude.cpp'
You can follow this link.
https://discuss.gradle.org/t/how-can-i-exclude-certain-java-files-from-being-compiled/5287/2
Also note that you should use exclude instead of excludes and srcDir instead of srcDirs.
I looked into the android source, it looks like you could update the filter to exclude your file. I don't know what version of the gradle plugin you are using, so I can't be sure what the underlying api is. You could try setting the PatternFilterable manually to exclude the file.
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
getFilter().exclude('**/FileToExclude.cpp')
}
}
}
}
I looked at Gradle Code Review, and saw that LanguageSourceSet was being used. Looking at the Gradle documentation for LanguageSourceSet, which you can access a SourceDirectorySet, which has a PatternFilterable that you can set the exclude on.
As it's still experimental there's not a much of documentation on Gradle Experimental. But with some experimentation I was able to dig a way on how to exclude some files, i.e.:
model {
//...
android.sources {
//...
jni {
//...
source {
excludes.add("<FILE PATH>") // You can have multiple excludes.add(...)
}
}
}
}
Note: the solution works on gradle-experimental 0.7.0
The easiest way is to set the properties in build.gradle:
sourceSets.main.jni.srcDirs = [] // now, AS will not try to compile your source files
sourceSets.main.jniLibs.srcDirs = ['libs'] // now, AS will pick up the compiled SO files from libs (where ndk-build will normally put them)
You can also define a "buildNative" task, to run ndk-build as part of compileTask, as defined in this answer.
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.
I would like to create a properties file named "dev.properties" using gradle. Here is my build.gradle code:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.8.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 16
buildToolsVersion "19.0.0"
defaultConfig {
minSdkVersion 16
targetSdkVersion 16
}
def prop = new Properties()
def propFile = new File("dev.properties");
propFile.createNewFile();
prop.store(propFile.newWriter(), null);
buildTypes {
release {
runProguard false
proguardFile getDefaultProguardFile('proguard-android.txt')
}
}
}
The file is created when I right click on the build.gradle and choose run. However it's not created when I make the entire project. How come?
I'm using android studio 0.4.6 with gradle 1.10.
It's creating the file, just not where you expect. Your script is creating the file inside the current working directory, and in Android Studio, that will be in Android Studio's distribution. There's a bug filed to make Android Studio consistent with the command line (https://code.google.com/p/android/issues/detail?id=65552) and put the working directory at the project root (well, that's assuming your working directory is set there when you issue Gradle commands), but the fix is actually difficult, and the real answer is you should probably never implicitly rely on the working directory, so that you can make your builds as bulletproof as possible.
If you do something like this:
def propFile = new File("${project.rootDir}/dev.properties")
it will put the file in your project's root directory. There's also project.projectDir, which will be your module directory; see http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html for more details on what's available to you.
As a side note, you should keep in mind this will run every time the build file is evaluated (because the android block is executed every time the build script is run), which could be more often than you want. It's more than just build time; it's project import time as well, and any time Android Studio decides to evaluate the build file, which happens when you open the project and also when you click the Sync Project with Gradle Files button.
Additionally, you should consider at what phase of the build process you want it to happen: is it script evaluation time, or do you want it to run after Gradle has done its analysis and is ready to actually start building things? You can read http://www.gradle.org/docs/current/userguide/build_lifecycle.html to find out more about that.
Sorry, I know it's a lot of information to drop on you when you're just trying to get something going, but those concepts will help you out pretty soon down the road.
I am having troubles understanding Build Flavors in Android Studio. I am trying to achieve a simple thing: buidling 2 signed APK's with a minor code change. The "pro" APK just has a different drawer.xml in res/layout/. I've read a few things in the Documentation and here on StackOverflow but I don't see anything happen with my build.gradle changes.
my current build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4.+'
}
}
apply plugin: 'android'
dependencies {
compile files('libs/android-support-v4.jar')
compile files('libs/GoogleAdMobAdsSdk-6.4.1.jar')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 17
}
productFlavors {
lite {
packageName = 'com.mikebdev.refuel'
}
pro {
packageName = 'com.mikebdev.refuelpro'
}
}
sourceSets{
android.sourceSets.pro {
res.srcDirs = ['src/main/res_pro']
}
}
}
I created a new folder:
/src/main/res_pro/layout/drawer.xml
What am I doing wrong here?
EDIT
I updated my build.gradle file above.
After resetting my whole Android Studio because of some other instabilities I am now able to choose in the bottom left corner my build variants (lite-debug, lite-release, pro-debug, pro-release) Why even those debug AND release variants?
This seems to work now as it should.
I added a answer below
After resetting my whole Android Studio because of some other instabilities I am now able to choose in the bottom left corner my build variants (lite-debug, lite-release, pro-debug, pro-release) Why even those debug AND release variants?
I created a whole new Project with Module and copy&pasted everything from my old project which I exported from eclipse a while back in there.
NOW it works.
My Android-Studio was kinda broken before my reinstall. More crashes than there should be, some strange behaviors ans such stuff.
What you're doing wrong is that you are putting your file in /src/main/res_pro/layout/drawer.xml and not setting it in the gradle. the default location for the flavor that you created would be:
/src/pro/res/layout/drawer.xml
With this build script you are using build types AND flavors. For changing the xml file you only need the flavors. Try to delete buildTypes and use the productFlavor block as child of android.
The changing of the res folder of the pro flavor should go into the sourceSets Block right after all the changes of the main sourceSet