Minimum Necessary files for an android build - android

Trying to find the bare minimum source and build files needed to build an android project in Android Studio. I want to publish to github and avoid uploading generated build files or binaries.
I do have a Android.gitignore from but I still see some more files getting pushed into the repo which may not be necessary. I understand the few obvious ones but about others, do I need them and if so kindly explain the usage.
So the question, do I need the following and if so then a short description of why?
root
build.gradle
gradle.properties
gradlew
gradlew.bat
settings.gradle
/app
app/build.gradle
app/proguard-rules.pro
/gradle (tested, android can re-download/generate following it if not present)
gradle/wrapper/gradle-wrapper.jar
gradle/wrapper/gradle-wrapper.properties

This question can have two different answers based on the meaning of the word needed.
First (the real one)
Assuming your project has currently those files, if your question is:
Should I commit these files on my Git repo?
The answer is yes, all of them, and I'm explaining why:
root
build.gradle -> defines the configuration for all the Gradle modules in your project (e.g. use the same remote repositories to download some Gradle plugins)
gradle.properties -> defines some optional flags used when building the app (e.g. enabling the incremental KAPT, enabling the AndroidX jetifier)
gradlew -> invokes the Gradle wrapper (which can be found under gradle/wrapper/gradle-wrapper.jar) to avoid to have Gradle installed when building your project on Darwin/Linux
gradlew.bat -> the same of gradlew but for Windows
settings.gradle -> defines the list of modules which are part of your project
app/
app/build.gradle -> defines the configuration only for your app module (e.g. its build types, its flavors, its version code and version name)
app/proguard-rules.pro -> defines the obfuscation rules when your app enables the minification
gradle/
gradle/wrapper/gradle-wrapper.jar -> provides the same version of the Gradle wrapper jar for all the users. This is very important because it forces the users to use the same version of the Gradle wrapper to compile your app
gradle/wrapper/gradle-wrapper.properties -> same as above, it defines which version of the Gradle wrapper you need
Second (the useless one)
Now, I'll give you the answer to the question:
Are these files strictly needed to compile an Android project?
To successfully compile an Android project with Gradle you just need the root build.gradle if you have Gradle installed on your machine or build.gradle + the wrapper files if you have not Gradle installed on your machine.
Theoretically you can:
put your application code in the root project and that avoids you one build.gradle and settings.gradle
disable the obfuscation and that avoids you proguard-rules.pro
remove gradle.properties and set the properties via command line
Obviously this solution won't happen on a real project scenario.

Related

whast the diff betn gradle Module and gradle Project in andorid Studio

Hello guys , actually Im little bit confused in the gradle files structure.
whats the diff betn
build.gradle(project: app_name)
build.gradle(module: app_name)
and below listed other files .
Thanks a lot for having a look .
any extra knowledge and information is deeply appriciated
From the official documentation
The top-level build.gradle file, located in the root project directory, defines build configurations that apply to all modules in your project. By default, the top-level build file uses the buildscript block to define the Gradle repositories and dependencies that are common to all modules in the project.
With few words you have always one in your root directory and it's used to define the settings for every module of your app
The module-level build.gradle file, located in each project/module/ directory, allows you to configure build settings for the specific module it is located in. Configuring these build settings allows you to provide custom packaging options, such as additional build types and product flavors, and override settings in the main/ app manifest or top-level build.gradle file.
Here you can simply specify the properties of the single module such as the dependency version and the minimum android sdk version
I think one way to better understand the concept is to deal with a multi-module app
In large projects this approach has many advantages such as the separation of concepts and the simplification of teamwork.

Jitpack builds successfuly, but jars are empty for every module

In recent release of our library we decided to add some kotlin-dsl features to our build, though for now we've added buildSrc build.gradle.kts and Dependencies.kts file containing libraries versions for easier use across all modules.
The problem is that this version builds successfuly on jitpack, but downloaded jars are empty. How do I fix this? Also all the resource files are present. The build log file also differs much from previous ones.
Problematic build log file
Working build log file
A link to library on jitpack: https://jitpack.io/#netigenkluzowicz/api_android
Github link
branch to reproduce these build problems is feature/kotlin, we're working to fix it on fix/jitpack-build branch
To Reproduce
Add this dependency to an Android project, sync and check classes.jars
implementation 'com.github.netigenkluzowicz:api_android:2.4.1'
What we did before this problem started to occur:
Added buildSrc directory with build.gradle.kts and Dependencies.kts.
We also extracted android { } block from our modules build.gradle files, it is now applied from android.gradle file.
I've already went through jitpack issues on github, all I found so far are build errors with kotlin-dsl from late 2018. Was following this guide to make a use of kotlin-dsl, though due to having issues with android { } block I didn't migrate all of our gradle files.

How to use different settings.gradle files for different environments

The problem
I have two projects, A (ui) and B (background service). Project A has a dependency on B. Project B gets published to a maven repository and included in project A like so in build.gradle
debugImplementation ('com.example:project-B:0.0.0-SNAPSHOT') { changing = true }
releaseImplementation ('com.example:project-B:1.6.2')
This works, but it's a pain to validate my service changes on the UI side. I need to publish project B to my nexus repo and resync project A.
I changed project A to the following:
build.gradle:
debugImplementation project(":project-b")
settings.gradle:
include ':project-a'
include 'project-b'
project(':project-b').projectDir = new File(settingsDir, "${project-b-path}")
I can have all my code in one IDE window and have A use local instance of B. But the problem is this will break on my build server since there is no local B project, only the one on nexus.
Is there a way to configure the settings.gradle for release vs debug? I can just commit my changes and overwrite the file on the build server, but I want to know if there are other ways?
You can use gradle command line to set which settings or build file should be used.
Settings File
-c, --settings-file
Specifies the settings file. For example: gradle --settings-file=somewhere/else/settings.gradle
Build File
-b, --build-file
Specifies the build file. For example: gradle --build-file=foo.gradle. The default is build.gradle, then build.gradle.kts, then myProjectName.gradle.
You can find more details here: Gradle docs: Environment options

Gradle disable the build of dependency projects

I have a a multi-project gradle project (Android) with following structure:
root
|-projA
|-projB
|-projC
|-...
In my specific case, projA is an app which uses projB (module). When I run build on projA, projB also gets built. I need to perform an action only on the project that was originally built (the project where the original action was performed on).
For this purpose I need to somehow get the name/path of this project. I need to do this in the afterEvaluate step if this matters.
Example:
gradlew :projA:build // Builds A and B -> I want only "projA"
gradlew :projB:build // Builds B -> I want "projB"
gradlew :projC:build // Builds A, B and C -> I want only "projC"
I am not sure how I can achive this, I hope someone of you can help me.
You can check the official doc:
The standard project dependencies are supported and makes relevant projects configured. If project A has a compile dependency on project B then building A causes configuration of both projects.
However you can disable the build of dependency projects (but pay attention!)
If you don't want depended on projects to be built when doing a partial build. To disable the build of the depended on projects you can run Gradle with the -a option.
Example:
gradle -a :projA:build
From the doc:
-a, --no-rebuild
Do not rebuild project dependencies.

How to add a dependent project to an android gradle project that builds a debug or release jar approprately

I need a clear example of how to extend an Android Gradle project with an arbitrary project.
By arbitrary I mean that it can't just use the 'java' plugin since it doesn't support buildTypes to my knowledge. I am currently using an 'ant' task for this, which has two targets for debug and release, however I don't see how to tie it into an Android project.
Assume that your dependent project must build pure Java source in two ways:
debug build that produces a debug version in 'purejava.jar'
release build that produces a release version in 'purejava.jar'
The jar 'purejava.jar' is to be placed such that the Android project (could be a multi-project) is able to reference it at compile time, and it must therefore be the correct build to support both the debug and release configurations of the Android project.
How should this be tackled?
Since I am new to Android Studio and Gradle, I don't have a clear idea of how to manipulate extensions generated by the Android plugin, which are not available until after project evaluation.
How should the Android project be made dependent on this pure java project?
If it weren't for the fact that you need debug and release versions of your library, then your Android app could depend on a plain Java module just fine -- you could set up the library with the java plugin and put a compile project statement in the app's dependencies and it would work fine.
However, the Java plugin is never going to understand Android's notion of build types (unless GradleWare adds it at some point), so you can't propagate that to your Java modules. You could set up your plain Java project as an Android library and use the android-library plugin (you'll have to dummy out the manifest and other Android-specific stuff it expects to see in Android libraries), but you'll run into a different problem: https://code.google.com/p/android/issues/detail?id=52962 is a bug that reports that the build type is not propagated to library modules.
Until that bug is fixed, or if you're unwilling to make your plain Java library an android library, I think your only approach is to make two different versions of your library, compile them to different jar files, and selectively pull in dependencies.
This is my answer, with following project structure:
MyProject
-- MyAndroidLib
-- JarProject
This represents the gradle top project 'MyProject' which has a sub-project 'MyAndroidLib' which is dependent on a pure java project 'JarProject' which is built with different code for debug than for release builds.
I'll take advantage of Android's 'debugCompile' and
'releaseCompile' configurations. In the Android sub-project ('MyAndroidLib') that is dependent on the jars, add following lines to the dependencies:
//MyAndroidLib build.gradle
def jarProject = project(':MyProject:MyAndroidLib:JarProject')
def jarPath = pcfProject.projectDir.toString()
dependencies {
....
compile jarProject
debugCompile files(jarPath + '/' + jarProject.debugJarName)
releaseCompile files(jarPath + '/' + jarProject.releaseJarName)
}
The 'jarProject' def is defined to simplify accessing it from the MyAndroidLib project. (If you know a better way ...)
The main point of this is to define a separate debug and release jar path for the 'debugCompile' and 'releaseCompile' configurations. The 'debugJarName' and 'releaseJarName' are defined in a gradle.properties file for the JarProject as follows:
//JarProject gradle.properties
debugJarName=jarproject_d.jar
releaseJarName=jarproject_r.jar
In the gradle file for JarProject define a task that builds BOTH jar files named by this properties file. In my case, they are built right in the project folder by the 'compile' target of an ant build file located in that project.
//JarProject build.gradle
apply plugin: 'java'
project.ext.set("debugJar", file(projectDir.toString() + "/" + debugJarName))
project.ext.set("releaseJar",file(projectDir.toString() + "/" + releaseJarName))
task buildJars(type: Exec) {
description 'Build the debug and release jars for the JarProject'
outputs.files debugJar,releaseJar
commandLine 'ant', 'compile'
}
task compileJava.dependsOn('buildJars')
artifacts {
buildJars
}
clean.dependsOn('cleanBuildJars')
clean << {
exec {
commandLine 'ant', 'clean'
}
}
I took advantage of the 'java' plugin since it defines a 'compile' interface, and I haven't figured out how to build this from scratch, or even from the 'base' plugin. This project takes advantage of the automatic 'cleanBuildJars' task created because I defined the outputs in 'buildJars' task. This is necessary in order to have them built as needed. I probably need to define the 'inputs' too, since if they change ...
If anyone sees how my first stumblings in the gradle/Android world can be improved, pls. add comments as needed.

Categories

Resources