Why so many metadata files in Android studio? - android

I created a new project in Android studio and got many files generated, where as my actual code is found in just one folder - src.
Why the so complicated structure? Please explain the motivation of putting meta-files at the root of the project instead of some inner folder named gradle.

Android build system consists of an Android plugin for Gradle. Gradle
is an advanced build toolkit that manages dependencies and allows you
to define custom build logic. Android Studio uses a Gradle wrapper to
fully integrate the Android plugin for Gradle.
Android Studio projects contain a top-level build file and a build file for each module. The build files are called build.gradle, and they are plain text files that use Groovy syntax to configure the build with the elements provided by the Android plugin for Gradle.
Gradle is an automated build toolkit that allows the way in which projects are built to be configured and managed through a set of build configuration files. This includes defining how a project is to be built, what dependencies need to be fulfilled for the project to build successfully and what the end result (or results) of the build process should be. The strength of Gradle lies in the flexibility that it provides to the developer.
For more info you may visit
Gradle Tutorial
Android Application Modules

First of all if you don't want to see those metadata... you can change it(see Image)..
gradle is required to compile your project. for example: In gradle file we specify minsdk version,maxsdk version and dependencies etc
To Know more about gradle go to http://gradle.org/the-new-gradle-android-build-system/

Why the so complicated structure?
IMHO the structure you are referring to is pretty straightforward but your assumption that all those meta-files are related with gradle is wrong.
Meta-files related with your android application are located inside the "app" sub-folder. You have some gradle files there because those are for the purpose of building that specific module.
As pointed out before in a previous answer the best resource to understand the file tree structure for this part is here.
You also have some metadata generated by the IDE (.idea sub-folder):
IntelliJ IDEA stores the configuration data for projects and their
components in plain text XML files making it easy to manage and share
project configuration data with others.
And .iml files:
A module is a discrete unit of functionality which you can compile,
run, test and debug independently.
Modules contain everything that is required for their specific tasks:
source code, build scripts, unit tests, deployment descriptors, and
documentation. However, modules exist and are functional only in the
context of a project.
Configuration information for a module is stored in a .iml module
file. By default, such a file is located in the module's content root
folder.
More info about can be found here.
Please explain the motivation of putting meta-files at the root of the
project instead of some inner folder named gradle.
As mentioned before in some previous answers some metadata is related with the configuration of your project itself and some is module-specific. One example is the build.gradle files. The global file has this comment:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
About the motivation I only assume it was for simplicity and to keep the semantics of the project structure. Other possibility is that it was just by convention.

Related

How to reference multiple aar artifacts in a com.android.library module?

In my Android application project I am trying to avoid referencing an external Maven repository in my project from where I would load multiple .aar artifacts which make up one SDK.
Instead, I would like to put the .aar files into my project and then reference them from one of my Gradle Android library modules.
I already tried different approaches - none worked, though.
Approach 1: Composite build (includeBuild)
Inspired by https://stackoverflow.com/a/72672032/35689
Here my artifact(s) cannot be resolved by Gradle.
I also tried this in isolation with the sample project - for some reason it does not work with my artifacts. In the example there is only one .aar file which might be the reason.
Approach 2: One module per aar
Inspired by https://stackoverflow.com/a/70074787/356895
Here I end up with this error:
jetified-externallibrary-1.2.3/res/values/values.xml:113:5-122:13: AAPT: error: style attribute 'attr/shimmer_auto_start' not found.
You have to manually add all of the .aar file's dependencies to your project in order to make this work. You will also have to substitute the maven dependency with the .aar file manually.
The reason is that an individual .aar file does not contain any metadata like maven coordinates, version, dependencies, etc. Therefore Gradle cannot handle any of this for you automatically.

Android Studio project's Git repository

In my project I have settings.gradle, gradle.properties and gradle-wrapper.properties files. Which of them should be checked in a Git repository?
All of those files should be commited as they all contain information critical to the build environment for the project.
The one exception would be if you needed to create a local.properties file to override or supplement those files on your computer specifically. The Configure your build section of Android Developer site has more information.
Additionally, when in doubt a good rule of thumb is to use a tool like gitignore.io to generate a Git gitignore file. It generally contains sane default rules on which files should be excluded from source control (and thus included).
Better to check all of them
settings.gradle --> This contains information which module should you include and the structure of project. Some plugin like gradle build scan also need to specify here.
gradle.properties --> Sometimes you want to specify JVM arg here, also some flag from android gradle plugin features, for example incremental build, kapt features, gradle flag feature (like configuration cache) etc.
gradle-wrapper.properties is defined gradle version used in your project. Some plugin may not compatible with other gradle version, so you should check it too in order to make sure everyone using the same version.

How does the apt-plugin work?

So,
We are using Dagger 2 in our Android application.
Code generated by
Dagger 2 is located in build/generated/source/apt.
In the documentation of apt-plugin it states that :"Using this plugin Android Studio will be configured to place the generated sources on the build path, preventing errors in the IDE"
If I remove apt-plugin from my build.gradle file, in a place where I use generated code I see compilation error. (Which is reasonable, generated code is not my source).
The questions are:
What does it mean that apt-plugin configures Android Studio so that it places generated code to build path ?
From what I know final dex file is generated from source folder that is specified in build.gradle, how do these generated files become the source ?
Thanks.
The apt-plguin is a gradle plugin and as such it runs with your build script.
This plugin configures apt to be run with your build and sources to be generated. It further adds the path of the generated files to your source sets, which is why the build succeeds and Android Studio recognizes the files as well.
For further information you could always have a look on the gradle documentation on Gradle Plugins.

Linked android modules generate unwanted .iml files

I'm ussing the usual way to link android studio modules to a project:
include ':app'
include ':coretools'
project(':coretools').projectDir = new File(settingsDir, '../base/CoreTools/app')
This works as expected but the problem is that this generates a coretools.iml file in the used module folder. I mean, in the above example a coretools.iml is generated under base/CoreTools/app.
The main concern is that this coretools.iml generated file has references to the project that used this module and it is a nightmare to use the module in different projects by different users with a CVS like git.
The question is: Is there any way to avoid this .iml creation? Is this "as designed" and can't be avoided?
Thanks
Please refer to the module documentation:
A module is a discrete unit of functionality which you can compile,
run, test and debug independently.
Modules contain everything that is required for their specific tasks:
source code, build scripts, unit tests, deployment descriptors, and
documentation. However, modules exist and are functional only in the
context of a project.
Configuration information for a module is stored in a .iml module
file. By default, such a file is located in the module's content root
folder.
Development teams, normally, share the .iml module files through
version control.
As you can see there is a lot of useful project-related information in the .iml files but the documentation doesn't state that you always must share those files though a CVS. If the .iml files are a pain for your development team just add them to your .gitignore file.
I finally ended just ignoring all *.iml in the library module but the one belonging go the module. Something like this in the .ignore file did it:
*.iml
!app.iml
being the app.iml the real/original module iml file.
Cheers.

Compiling module from another project

I have my main project with some modules: :app, :anotherModule, ... .
Then I forked a library on github and pushed it down in another project. It has two modules, a library :library and a sample app :sample.
What I'm trying to do is to integrate :library in my project at compile time, i.e. without copying files (as someone has suggested here).
What I did
I edited my project settings.gradle and added:
include ':library'
project(':library').projectDir = new File(settingsDir,'../ForkedLibrary/library')
referencing the folder of the forked library. At the same time I added compile project(':library') to my app module.
What's wrong
Compiling fails with:
Could not find property 'ANDROID_BUILD_SDK_VERSION' on project ':library'
I know why it happens: ForkedLibrary/library/build.gradle is referencing some project values in ForkedLibrary/gradle.properties, which is something like:
ANDROID_BUILD_MIN_SDK_VERSION=14
ANDROID_BUILD_TARGET_SDK_VERSION=23
ANDROID_BUILD_SDK_VERSION=23
ANDROID_BUILD_TOOLS_VERSION=23.0.0
... + LOTS of other stuff, POM_ info, version names, ...
I could fix this by copy-pasting these lines into my project gradle.properties, but it makes no sense to have :library-specific stuff in my own gradle properties files. That ForkedLibrary properties files includes things unrelated to my project, like original developer info and other POM_ fields.
So
How to solve this (without including ForkedLibrary properties in my own gradle.properties file)?
It should be a comment, but it is too long. I will delete it if it doesn't help you.
The ForkedLibrary/library/build.gradle as you described in your question is using the ForkedLibrary/gradle.properties.
It works only in the ForkedLibrary specific project because the other project uses its own gradle.properties.
I guess the library/build.gradle file has somenthing like:
project.VERSION_NAME
You can refer the official doc:
The configuration is applied in following order (if an option is configured in multiple locations the last one wins):
from gradle.properties in project build dir.
from gradle.properties in gradle user home.
from system properties, e.g. when -Dsome.property is set on the command line.
In this case you have to copy the properties in your build.properties
There is an alternative that I have never tried in this case, something like this:
processResources {
expand(project.properties)
}
As you can read in the official doc:
Copies resources from their source to their target directory, potentially processing them. Makes sure no stale resources remain in the target directory.
And the expand method is:
Expands property references in each file as it is copied.

Categories

Resources