I try to have 2 independent projects in AndroidStudio :
/some_root/Lib1
/some_root/Project1 ('app')
The build lifecycle of the 2 projects are separated (2 gits, 2 jenkins target, ...) and Lib1 is used by some other projects.
When I build Lib1, I want to generate a versioned aar.
When I build Project1, that depends on Lib1, I want to generate an apk WITHOUT rebuilding my lib each time (aar installed on local maven or nexus).
I would love to be able to see/edit/refactor my local library files next to my Project1 (if it have the required snapshot version in gradle dependency) from AndroidStudio.
And in the same time, I need to be able to reproduce this setup on some other projects (eg Project2) and switch easily from one to the other.
Is it event possible?
Note: I have tried some configurations in settings.gradle to load a project from another URL but it implies dependency build each time, and it's not possible for me. I have also failed to use AS dependency system (I suppose it use gradle each time so it's not viable too).
Related
Our Android project is a monorepo containing couple of app modules, and even more library modules. One of the libraries should be also accessible to other developers so we have decided to deploy it on MavenCentral. Let's call it the library L. This library however also contains dependency within the monorepo to another module (let's call it a module m). In order to test whether the library L is correctly accessed by the other developers, we have created a demo Android project. But when trying to include the dependency of the publish library L, generally all works great except that the module m could not be resolved in the demo Android project.
Understandingly, the module m could not be resolved due to it being available neither on MavenCentral nor as an AAR file. We cannot publish the module m on MavenCentral since it should not be available for others to get, but including it as an AAR file, doesn't work either. Terminal throws an error:
Direct local .aar file dependencies are not supported when building an AAR. The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR. Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error).
So the question comes - how can a project - that includes a submodule that can't be exposed, be published to repository like mavenCentral?
How can I access Activity from AAR library which is not directly included into the project but is embed to another AAR library?
I got an error java.lang.NoClassDefFoundError: Failed resolution of:
The class is public and if I compile it directly in project application it can be used without problem.
I included an AAR to my project like this :
ProjectApplication
|
+--sharedModule (android library - AAR or any working solution)
| |
| +--Module1 (android library - AAR or any working solution)
| |
| +--Module2 (android library - AAR or any working solution)
| |
| +--Module3 (android library - AAR or any working solution)
compile (project(":sharedFrameWork")){ transitive = true }
which has also included in itself 2 other AAR libs. They are also set to be Transitive. When I try to open an activity from one of the sub AAR libraries. I got the class not found error. But when I include that particular AAR into my application directly the class is found and can be used. It looks like I do not have access to any sub AAR libraries which are not included directly into my Application.
To better describe my situation :
I have to create an integration AAR library (later called 'sharedFrameWork') which includes multiple AAR libraries and is later embed into an application.
Multiple AAR -> Shared AAR 'sharedFrameWork' -> Application
The sharedFrameWork has some method which starts some activities from the included AAR's or set up basic communication with the server. I have read that if all the dependencies are set to be transitive it will make it work, but unfortunately it does not.
So When I call from my application a method which should start an activity from one of the included AAR in sharedFrameWork the app reports me that no such a class was found.
But when I include that AAR module right to my application not to sharedFrameWork, and then call the exact same functionality the Class is found and the project is working as it is designed. Can you help me how can I create this sharedFrameWork to be working as it is designed? Can it be done by using AAR or should I take another approach? If any other way it can be done and the result will be that I can deliver just one library and it will work as designed so it can access its submodules I will go with it, feel free to point me out the best approach for this problem.
If I get it right, you want to create a fat AAR and achieve a single import of several libraries.
Now, since you haven't provided more info, I'm going to assume you are using gradle 2. In gradle 2, submodules don't share their dependencies. neither does anything you put into the libs folder. So, first, I would upgrade your projects to gradle 3, switch from "compile" command to "api" command, and check.
If that does not work, the next step would be to apply the gradle maven plugin to each one of your modules, and deploy the resultant AAR file to either your local maven repo (automatically created when you install maven), or a remote repo, like jitpack. If you have AARs/JARs into the libs folder, deploy them to a repo too and import them from there (libs folder scope is local in gradle 2, and in general, is a bad idea to use it instead of a centralized repo. You can even use github as a repo). Then, use the artifacts.
Finally, the last solution for your problem would be to use "shading"; the process to pack several different artifacts into one. If you can't upgrade to gradle 3, or deploy the artifacts somewhere (unlikely), this is what you should do. There are several plugins for this:
https://plugins.gradle.org/search?term=shade
https://github.com/zawn/android-shade-plugin
if those don't work for you, switch to maven and use the maven shade plugin.
As a side note, you should not provide a fat AAR. Is better to keep your framework in separate modules. That will speed up your build process and allow you to save space if you don't require some classes. Even in a multimodule project, you can create separate artifacts, one for each module, and import them as you need. Just avoid circular references (a module A that requires a module B which requires module C which requires module A) and you'll be fine.
I was wondering what is the recommended way of including library projects in an Android Studios gradle like this:
First way:
compile 'de.greenrobot:greendao:2.1.0'
Second way:
compile files('libs/greendao-2.0.0.jar')
and what are the pros and cons.
In the first case gradle is completely handling the process of dependency management, i.e. downloading the jar and including it in your project.
In the second case you have to manually download the jar and include it in the libs folder.
The simpler and preferred way is the first.
First way: compile 'de.greenrobot:greendao:2.1.0'
PRO:
Easy, quick to update
CON:
Internet connection required when updating your gradle file
Second way: compile files('libs/greendao-2.0.0.jar')
PRO:
You can make changes to the library and those won't be overwritten.
Like Qian Sijianhao said, it's quicker to build.
CON:
More work to set up, update
In most cases I think you want to go with the first way.
Trust me, the second way will save lots of your building time.
By the way , time is money.
In the first way, i.e:
compile 'de.greenrobot:greendao:2.1.0'
compile 'com.library.sample:library:x.x.x'
Gradle will finding these dependencies, and making them available in your build. If your dependencies have a dependencies, gradle will also finding them and include it for the project. So you don't need to manually add all the dependencies.
Quoting from Gradle documentation:
7.1. What is dependency management?
Very roughly, dependency management is made up of two pieces. Firstly,
Gradle needs to know about the things that your project needs to build
or run, in order to find them. We call these incoming files the
dependencies of the project. Secondly, Gradle needs to build and
upload the things that your project produces. We call these outgoing
files the publications of the project. Let's look at these two pieces
in more detail:
Most projects are not completely self-contained. They need files built
by other projects in order to be compiled or tested and so on. For
example, in order to use Hibernate in my project, I need to include
some Hibernate jars in the classpath when I compile my source. To run
my tests, I might also need to include some additional jars in the
test classpath, such as a particular JDBC driver or the Ehcache jars.
These incoming files form the dependencies of the project. Gradle
allows you to tell it what the dependencies of your project are, so
that it can take care of finding these dependencies, and making them
available in your build. The dependencies might need to be downloaded
from a remote Maven or Ivy repository, or located in a local
directory, or may need to be built by another project in the same
multi-project build. We call this process dependency resolution.
Note that this feature provides a major advantage over Ant. With Ant,
you only have the ability to specify absolute or relative paths to
specific jars to load. With Gradle, you simply declare the “names” of
your dependencies, and other layers determine where to get those
dependencies from. You can get similar behavior from Ant by adding
Apache Ivy, but Gradle does it better.
Often, the dependencies of a project will themselves have
dependencies. For example, Hibernate core requires several other
libraries to be present on the classpath with it runs. So, when Gradle
runs the tests for your project, it also needs to find these
dependencies and make them available. We call these transitive
dependencies.
Gradle will store the downloaded library to your USER_HOME/.gradle. In Linux, it will store it in /home/user/.gradle/caches/modules-2/. in Mac it will store it in ~/.gradle/caches/modules-2/.
By the way, if you have used the library, you can set Android Studio to use a local cache of the library.
In the second way, you need to manually add the library for your project. And you also need to include all the remaining dependencies of the library. This is so error prone.
I work for a company which has a android mobile application developed by an offshore team. I have access to GitHub repositories.
I am piecing together the android app block by block and it is giving me hell.
How do I distinguish between module, libraries, jar, library projects, gradle projects, aar and jar. Can someone please give me a practical definition. NOT out of a freaking google search. I have Google too.
PS yes I am a noob and not proud of it.
I'm just giving a brief description about each of these. I hope I'm clear.
Module : A Module is an component of your application that can build / test independently and re use it in another application if required.
Libraries : AAR files, JAR files etc.
JAR : Java library
AAR : Just like JAR, only difference is that it also contains android specific files like resources etc.
Gradle Project : Gradle is just a build system which is used by Android Studio to build the android project. Its very much powerful as compared to the build system which was used in Eclipse earlier.
Library Project : An Android library project is similar to an Android app project in that it also includes a project manifest file in the project’s root directory. Also, this directory contains src, res, and other directories that you also find when building an app project.
However, there is a significant difference. You cannot compile a library project into an APK file because a library project doesn’t describe an app. Instead, it provides reusable code and resources that contribute to an app when the app’s project and source code refer to the library project. At build time, this code and these resources are merged into the app’s APK file.
To explain more on this, let me give you an example :
Say you want to use a networking library volley for making API calls, now since this is an open source library from Google you can clone it making customisations as per your requirement.
You can make volley library as your Library Project, build it independently, unit test, etc.
Now say you started building an application where you need to make HTTP calls so you need to add volley library to your project. You have two choices for that :
Compile your library project volley, generate the aar file and add it your app Project.
Add Volley as module in your project. (If you choose this option you can make changes to volley library in same studio project since it will act as a component in your project)
Please let me know if something is not clear.
1.) Module
A module is a collection of source files and build settings that allow you to divide your project into discrete units of functionality. Your project can have one or many modules and one module may use another module as a dependency. Each module can be independently built, tested, and debugged.
There are 4 type of module in Android Studio.
Phone & Table Module
Android Wear Module
Android TV Module
Glass Module
2.) Support Library
The Android Support Library offers a number of features that are not built into the framework. These libraries offer backward-compatible versions of new features, provide useful UI elements that are not included in the framework, and provide a range of utilities that apps can draw on.
Support libraries provide a range of different features:
Backward-compatible versions of framework components.
UI elements to implement the recommended Android layout patterns.
Support for different form factors.
Miscellaneous utility functions.
3.) Jar file
JarFile is used to read jar entries and their associated data from jar files.
for more detail visit this : https://developer.android.com/reference/java/util/jar/JarFile.html
4.) Android Library Project
The Android team introduced a new binary distribution format called Android ARchive(AAR). The .aar bundle is the binary distribution of an Android Library Project.
An AAR is similar to a JAR file, but it can contain resources as well as compiled byte-code. This allows that an AAR file is included in the build process of an Android application similar to a JAR file
5.) Gradle and Gradle Project
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. The Gradle system is a self-contained, command-line based environment that can be integrated into other environments through the use of plug-ins. In the case of Android Studio, Gradle integration is provided through the appropriately named Android Studio Plug-in.
for more detail visit this : http://www.techotopia.com/index.php/An_Overview_of_Gradle_in_Android_Studio
I work on a big project at work, i have been herited 3 months ago. At the moment the project structure is like this :
Engine : its a library with my entire code (all java classes) with some extern libraries
App : its a android project but it is just a wrapper for have 2 declinaisons-flavor of the app (different name and icon for commercial purpose). The engine lib is integrated to this app.
Additionnaly, sometimes I do build the engine to .aar for one client who use the library without the app wrapper.
My big problem : the last developepr of this project dont good know gradle and android structure, it is some strange res added twice in Engine and App/ build script / extern lib added twice...
So, before i work on a new major version, i want to refator the build system and simplify it ! In the best world, i want to delete the lib project, add the Engine code to the App, for have just 1 project app and use power of flavors for managing specifics parts.
If i have flavors like this :
one
two
lib
It is possible to use flavor "lib" to get a .aar ?
If you have another solution for simplify or resolve my problem, im over. Thanks in advance :)
Having, has you described it, a single application module that outputs both .aar and .apk is not possible afaik, your module has to be a library OR an application, not both. (i.e. in your build.gradle : apply plugin: 'com.android.application' or 'com.android.library').
My guess here will be (Android studio 1.5.1) :
A single Android Studio project,
Two modules, one library module and one application module (File -> new... -> New module... -> one "Android Library" and one "Phone or tablet module")
In the app module, the 2 flavors for your branding.
Integrate the library module into your app module as a dependency (in your app build.graddle dependencies section : compile project(path : ':yourlibrarymodule'))
Your ressources can either be stored either in your library (usable in your lib and your app without duplication), in your app in the main flavor (usable in your 2 flavors without duplication) or in your two flavors.
Therefore, you can produce the .aar by building your library module, and the two .apk by building your app module.