In this thread both project structures were already compared. The question that is still open for me is if there is something that won't work or any disadvantages or staying with the old eclipse project structure after migrating to Android Studio? We have migrated a really big project to Android Studio staying with the old structure and all works fine, changing the structure of such a big project would be really complicated, are there any advantages with doing so?
You can stay with old Eclipse project structure. All you has to do is set up correct path to your code in build.gradle config file:
android {
...
sourceSets {
main {
manifes.srcFile 'path/to/AndroidManifest.xml'
java.srcDirs = ['path/to/src']
resources.srcDirs = ...
aidl.srcDirs = ...
res.srcDirs = ...
assets.srcDirs = ...
jni.srcDirs = ...
}
androidTest {
java.srcDirs = ['path/to/android/tests']
res.srcDirs = ...
...
}
test {
java.srcDirs = ['path/to/unit/tests']
}
}
}
Only thing that may be confusing that if you are using proxy and configure it in AndroidStudio, it will inject parameters as plain text in your root gradle.properties file. If you are using gradle.properties, i.e. you are inject variables from Jenkins, it can be frustrating, and also you can suddenly commit this file with all your credentials. To avoid it, you can use project structure with modules:
/root
-build.gradle
-gradle.properties
-module/
-module/build.gradle
-module/gradle.properties
In this case, you can hold your gradle variables in module/gradle.properties, and root gradle.properties will be used for AndroidStudio purposes.
I am trying to swap some resources in the res/raw folder and the jniLibs/armeabi folder based on whether its a release buildType or a debug buildType. I currently have two product flavors as well.
The build.gradle file:
apply plugin: 'com.android.application'
android {
dexOptions {
preDexLibraries = false
}
compileSdkVersion 21
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.test"
minSdkVersion 17
targetSdkVersion 22
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
productFlavors{
phone{
applicationId "com.example.testPhone"
}
tablet{
applicationId "com.example.testTablet"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets{
release{
res.srcDirs = ['androidRelease/res/raw']
}
}
}
dependencies {
compile project(':facebook')
}
Is using sourceSet the right way to do so? If it is, what folder should be created so that it swaps the appropriate resources based on the buildType only and irrespective of the productFlavors?
EDIT: Is it even possible to swap jniLibs and raw folder resources?
Folder Structure:
src/main/jniLibs/armeabi
phoneRelease/jniLibs/armeabi
tabletRelease/jniLibs/armeabi
Is the folder structure correct.?
EDIT 2:
Based on Xavier's answer should the gradle look like this:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
res.srcDirs = ['androidRelease/res/raw']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
res.srcDirs = ['androidRelease/res/raw']
}
}
}
I keep reading lot of conflicting answers, some of them mention that you just need separate folders based on build variant and some mention about having to use sourceSet?
Thanks!
some of them mention that you just need separate folders based on build variant and some mention about having to use sourceSet?
Gradle/Gradle for Android has an expected structure for a sourceset:
Android resources in res/
Java source tree in java/
Pre-compiled JNI libraries in jniLibs/
Assets in assets/
Etc.
Where the sourceSets closure comes into play is if, for a given sourceset, you want a different structure:
Android resources in foo/
Java source tree in bar/
Pre-compiled JNI libraries in ickyNativeStuff/
Assets in assetsBecauseThatSeemsLikeADecentName/
Etc.
Each build type, product flavor, and build variant can have a separate sourceset (as can androidTest for instrumentation testing), to go along with main. They are named the same as the build type/product flavor/build variant. These will be in the stock structure, unless you use sourceSets to change things.
So, to roll all the way back to:
I am trying to swap some resources in the res/raw folder and the jniLibs/armeabi folder based on whether its a release buildType or a debug buildType
In the case of resources, other sourcesets overlay main. So, if you have src/main/res/... and src/main/debug/... and src/main/release/..., and you are doing a debug build, whatever is in src/main/release/... is ignored (as we aren't doing release) and whatever is in src/main/res/... and src/main/debug/... will be used. If there is the same resource in both (src/main/res/raw/boom.ogg and src/debug/res/raw/boom.ogg), the debug one trumps the main one.
I have not experimented with varying jniLibs/ by build variant. My guess is that it will behave more like Java code, where you cannot have conflicts between what is in a build variant's sourceset and what is in main, but that's just a guess. So, you can have the debug version of your compiled JNI code in src/debug/jniLibs/ and the release version of your compiled JNI code in src/release/jniLibs/. Only have in src/main/jniLibs/ any libraries that are not varying. That being said, as I mentioned, I haven't tried this, and so there may be hiccups here.
So, I would expect you to not have a sourcesets closure in build.gradle, and to just use the stock sourcesets structure, for your various bits:
src/
main/
...
debug/
jniLibs/
res/
raw/
release
jniLibs/
res/
raw/
Anything that's normally under src/main/ can be put in a different folder:
src/<element>/AndroidManifest.xml
src/<element>/java
src/<element>/res
src/<element>/assets
src/<element>/resources
src/<element>/jni
src/<element>/jniLibs
src/<element>/aidl
src/<element>/rs
Where element is the name of a build type or a product flavor. If your variant includes such a element (build type or flavor), then that source set is also used in addition to src/main
Note that the location is really not relevant if you have configured it.
What matters is that there is a android.sourcesets.main element that contains the sources common to all variants, and each variant has a set of sourcesets.
For instance if you have a flavor phoneRelease it's really using the following sourcesets:
android.sourcesets.main
android.sourcesets.phone
android.sourcesets.release
android.sourcesets.phoneRelease
If you have another variant tabletRelease, it'll use the following:
android.sourcesets.main
android.sourcesets.tablet
android.sourcesets.release
android.sourcesets.phoneRelease
So the phone/tablet sourceset is different and is where you'd put the variant specific sources, unless you want to be even more specific and use the phoneRelease/tabletRelease sourcesets (though those are less used generally.) By default these would be src/phone/... and src/tablet/... (or src/phoneRelease/...) but you can change that however you want and as long as it's connected to the android.sourcesets.* objects it'll be fine.
for example, doing:
android {
sourcesets {
phone {
jniLibs.srcDirs = ['phoneRelease/jniLibs/']
}
tablet {
jniLibs.srcDirs = ['tabletRelease/jniLibs/']
}
}
}
is fine. But do be aware that you only changed the jniLibs folder and not the other source elements (java, res, etc...)
If you kept the default location for the main sourcesets, I'd just keep everything under src/
You can see more info about sourcesets and how multiple sourcesets are combined here: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Sourcesets-and-Dependencies
To use flavors to vary source sets,
productFlavors{
phone{
}
tablet{
}
}
Now structure your code like,
src
main
phone
tablet
The code in main is common between both flavors, but the code in phone or tablet is only included when the respective flavor is built. That's it, you don't need to do anything else.
The structure under phone and tablet is the same as under main (res, java, etc). You can also have a custom AndroidManifest.xml under the flavor directory. Gradle attempts to merge the flavor's AndroidManifest.xml with the one in main. In some cases you have to provide rules for how to merge.
My Android project contains some property files in the package structure. To read this property I use MyClass.getResourceAsStream("someProperties.xml"). MyClass has no access to a Context.
After migrating to Android Studio the someProperties.xml is not moved into the resulting package structure. Therefore my code can't find the file.
What can I do to read my file again? How can I modify the gradle build to have the file copied to my package structure again or is the a possibility to read resources without a context and put the file into assets?
I guess you have not specified within gradle where those resources are located.
Defaults are different in Eclipse ADT and Android Studio.
Here are defaults for Eclipse (when java sources already in src/main/java)
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
see MAKE ANDROID ECLIPSE PROJECT READY FOR ANDROID STUDIO, YET KEEPING IT ACCESSIBLE FOR ECLIPSE USE TOO
I'm trying to move my current android project to a Gradle project, so here what I've done so far:
add gradle to eclipse
generation of build.gradle file
create ANDROID_HOME environment variable in Windows 7
at the root of my project in command prompt: gradlew build
So now, I've got a new folders structure in my project:
It's my first time with gradle, I guess I missed something and I would like to know if to finish this migration I have to delete the src and res directories (in blue) ? For me I just have to get a new structure of folders after the generation of gradleview build..
And if what I've generated looks like to a gradle project ?
If your project structure does not fit to android studios structure you can add your folders to the source set in the gradle file of your app.
So your android studio will match the correct folders
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Project-Structure
sourceSets {
main {
// manifest.srcFile 'src/main/AndroidManifest.xml'
// java.srcDirs = ['src/main/java', 'build/generated/source/apt/${variant.dirName}']
// resources.srcDirs = ['src/main/resources']
// res.srcDirs = ['src/main/res']
// assets.srcDirs = ['src/main/assets']
}
}
as copied from here
There was typo: use gradlew build or gradle build
You can keep Eclipse folder structure and configure it in build.gradle
Yet I would recommend to move source into src/main/java.
Eclipse would be quite OK with that.
http://www.nodeclipse.org/projects/gradle/android/Make-Android-Eclipse-project-ready-for-Android-Studio
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.