Building an android project referencing android library project using ant / teamcity - android

I got a android project say project A ..now this project project A depends on a Android lib project say LibX. Now LibX depends on another android library project LibY. How can I build my project using ant.
Here is the android documentation I am referencing to -
http://developer.android.com/guide/developing/projects/projects-cmdline.html
Here's what it says
At build time, the libraries are merged with the application one at a time, starting from the lowest priority to the highest. Note that a library cannot itself reference another library and that, at build time, libraries are not merged with each other before being merged with the application.
Is there a way around this?

by Android Developer site: source in http://developer.android.com/tools/projects/index.html , section at Library Projects:
"... Structurally, a library project is similar to a standard Android
application project. For example, it includes a manifest file at the
project root, as well as src/, res/ and similar directories. The
project can contain the same types of source code and resources as a
standard Android project, stored in the same way. For example, source
code in the library project can access its own resources through its R
class.
However, a library project differs from a standard Android application
project in that you cannot compile it directly to its own .apk and run
it on an Android device. Similarly, you cannot export the library
project to a self-contained JAR file, as you would do for a true
library. Instead, you must compile the library indirectly, by
referencing the library in the dependent application and building that
application.
When you build an application that depends on a library project, the
SDK tools compile the library into a temporary JAR file and uses it in
the main project, then uses the result to generate the .apk. In cases
where a resource ID is defined in both the application and the
library, the tools ensure that the resource declared in the
application gets priority and that the resource in the library project
is not compiled into the application .apk. This gives your application
the flexibility to either use or redefine any resource behaviors or
values that are defined in any library.
To organize your code further, your application can add references to
multiple library projects, then specify the relative priority of the
resources in each library. This lets you build up the resources
actually used in your application in a cumulative manner. When two
libraries referenced from an application define the same resource ID,
the tools select the resource from the library with higher priority
and discard the other.
Once you have added references to library projects to your Android
project, you can set their relative priority. At build time, the
libraries are merged with the application one at a time, starting from
the lowest priority to the highest.
Library projects can reference other library projects and can import
an external library (JAR) in the normal way. ..."
I went through a similar problem when using the library Rajawali (version 0.9). There was a need to distribute a file. Single jar and applications would use this JAR to display 3D screens. The problem was that our library was a customization that used library resources Rajawali. So two project structures were created (such as library project). When generating. JAR application that used the resources did not work for the reasons you explain above), this because the library uses Rajawali features of images to be loaded with IDs that were not recognized in the version of the target application.
The solution of the single JAR can be validated by modifying the code to not use the Rajawali resources via R.raw.X (Android approach) to go to use the folder assets / , and make the component use Rajawali AsseptManager to open resources. The solution was exported JAR folder with the internal assets / and the bytecode (. Class) and our LIB Rajawali.
By Fat-JAR Eclipse PlugIn (or 0.0.31 +) [update site http://kuruczgrafika.de/fatjar] could generate a single JAR and use it in the target application. The ANT script was used to run the XML below and a JAR file was generated. The file "lib3d_NAME_HERE.jar" (.JAR) will be generated in the /build/lib3d_NAME_HERE.jar
<?xml version="1.0"?>
<project name="lib3d_NAME_HERE" default="main" basedir=".">
<property name="projectPath" value="D:\Development\lib3d_NAME_HERE"/>
<!-- this file was created by Fat-Jar Eclipse Plug-in -->
<!-- the ANT-Export is in a very early stage, so this -->
<!-- is only experimental, ANT 1.6 or above is -->
<!-- required, feedback is always welcome: -->
<!-- http://sourceforge.net/projects/fjep -->
<!-- uncomment the following lines if using ANT outside Eclipse -->
<!--
<property name="fjepPath" value="reference:file:plugins/net.sf.fjep.fatjar_0.0.31/fatjar.jar"/>
<taskdef name="fatjar.build" classname="net.sf.fjep.anttask.FJBuildTask" classpath="${fjepPath}"/>
<typedef name="fatjar.manifest" classname="net.sf.fjep.anttask.FJManifestType" classpath="${fjepPath}"/>
<typedef name="fatjar.exclude" classname="net.sf.fjep.anttask.FJExcludeType" classpath="${fjepPath}"/>
<typedef name="fatjar.jarsource" classname="net.sf.fjep.anttask.FJJarSourceType" classpath="${fjepPath}"/>
<typedef name="fatjar.filesource" classname="net.sf.fjep.anttask.FJFileSourceType" classpath="${fjepPath}"/>
-->
<!-- uncomment the above lines to use ANT outside of Eclipse -->
<target name="main">
<fatjar.build output="build/lib3d_NAME_HERE.jar">
<fatjar.manifest/>
<fatjar.filesource path="${projectPath}/bin/classes" relpath=""/>
<fatjar.filesource path="${projectPath}/assets/" relpath="assets"/>
</fatjar.build>
</target>
</project>

Related

Difference between module, libraries, jar, library projects, gradle projects, aar and jar

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

Adding library with and without resources in android

I'm new to android development. I wanted to implement Navigation Drawer feature in my application, which requires android.support.v4.jar file to be included in my project. I'm using Android Studio to develop my application so I included the compile "com.android.support:support-v4:18.0.+" in my build.gradle file as mentioned in https://developer.android.com/tools/support-library/setup.html. My project is working fine, I was able to successfully include my library. I did adding library without resources.
What I couldn't figure out is the difference between adding library without resources and adding library with resources. Does adding library with resources mean including some sample project?
Thanks
For Android Studio projects using Gradle (which is what your project is), there isn't an important distinction between libraries with resources and without resources. The Gradle build system's support for Android is more advanced than anything available to Eclipse and can support libraries with and without resources the same way (you just add the compile statement to your dependencies as you have; you can also do it more easily via the Project Structure dialog).
In Eclipse, if you want to include a library with resources, you have to add it as a project (similar to an Android Studio module) to ensure the resources get included directly; there you can't include resourceful libraries as simple jar files.

Passing properties to Android library project build file

I have an Android app project that is split into a free and a paid version. Everything that is common to both projects resides in an Android library project called "core". Then I have actual Android app projects for both the paid and the free version.
I'm using Ant scripts for building these two APKs. The paid version sets a property that tells the "core" project that the paid version is building. The free version tells the core project that the free version is building.
That used to work perfectly fine until Google decided to release ADT 22. Now the "core" project doesn't pick up these build properties anymore.
I suspect that library projects are built in a separate Ant build environment / process now.
So here's my question: how do I define properties for referenced Android library projects within an app project's build.xml file? How to pass over properties to these library project builds?
And where in the SDK's build.xml file are library projects actually compiled? I guess that would be the right spot to look into.
Thanks for your time.
EDIT for clarification
You have to create a modified copy of the original build.xml file from the Android SDK (see SDK-Folder/tools/ant) and also keep it up to date every now and again when Google releases an ADT update by merging the differences (and keeping the own modifications of course).
The build.xml file builds library projects using a <subant> task, which basically starts a separate build environment that does not automatically see any properties of the calling scope (which would be the app project's build environment).
However, within that subant tag you can export properties of the caller's scope to the library's build XML using a <propertyset> tag. Look for the following code block in your copy of build.xml and make a modification as shown below:
....
<echo level="info">Building Libraries with '${project.libraries.target}'...</echo>
<!-- no need to build the deps as we have already
the full list of libraries -->
<subant failonerror="true" buildpathref="project.library.folder.path" antfile="build.xml">
<!-- *** ADD THIS: *** -->
<propertyset id="project.library.buildargs">
<propertyref prefix="project.library.buildargs" />
</propertyset>
<target name="nodeps" />
<target name="${project.libraries.target}" />
<property name="emma.coverage.absolute.file" location="${out.absolute.dir}/coverage.em" />
</subant>
....
Above example makes all app project build.xml properties that are prefixed with project.library.buildargs. visible to all referenced Android library build scripts.
An alternative solution I have found to provide different values for my free version vs my paid version is to use [resources]. The Android build chain allows application projects to override the resource values set in the shared library project.
So for example, you can have a boolean resource in any XML file in res/values:
<bool name="paid_version">false</bool>
Of course, the paid version has the same resource in its own res/values subdirectory with a value of true.
Then from an Activity subclass or any other class with a Context, you can do the following:
if (getResources().getBoolean(R.id.paid_version)) {
// Do the paid version code here
}
This has the advantage that it is fairly easy to implement. On the down side, this is a run-time check based on dynamic code. This means that the code cannot be optimized away by the compiler or any other static analysis tool when the resource value is set to false.

Expose an "Android Library Project"'s included jars to Projects which reference them

One of the newer functions of Android is the ability to create a Library Project.
This is great for unit testing and sharing common functionality across many apps you may be developing, but I seem to have stumbled upon a bug in their implementation.
When you have the following situation:
-LibraryProject contains LibraryProject/libs/folder/lib.jar in it's build path.
-ReferencingProject references LibraryProject.
From ReferencingProject you don't have access to anything inside lib.jar (Such as constant's used to communicate with methods in the Library Project).
A solution to this is to include "lib.jar" as an external library in the referencing project but this approach begins to negate the benefits you gain from having a self contained Library Project by creating multiple manually added references to resources which could move/change during the development of the library project (not to mention cause some pretty confusing errors).
Is there any way to expose an included libs classes to the referencing project without having to manually reference them as external jars?
As #Selvin says,
In the Library Project you can specify which libraries you want to mark as "exported" in the window brought up by using: Project properties => Java Build Path => Order and Export. From this example you would check libs/folder/lib.jar.
Clean and build the Library Project and the "exported" libraries are now included in the produced jar.
EDIT
This is a symptom of upgrading to ADT 17 - (Android Team: Perhaps put a few warnings on your release notes when an update breaks existing architectures?)
http://tools.android.com/recent/dealingwithdependenciesinandroidprojects
If you don't want to add the library to the "Order and Export" then placing local jar's in /libs/ base folder will automatically add it to "Android Dependencies" which are exported in the jar created from your shared library.
EDIT2
Recent ADT upgrade would have you also manually select "Android Dependencies" as "Exported" in your Java Build Path. Again, warning would be nice.

Does slicing a large Android project into Android libraries improve build time?

I have a rather large Android project, and it takes considerable amounts of time for the sdk to do the resource-parsing / dexing / etc. I'd like to improve this somehow.
I've read that Android library projects can contain resources now too. So we can also put Activities, Fragments, etc. in them.
Does this mean, that if I export parts of my large project into library projects which I reference from the main project, then I don't have to rebuild the already built (and not modified) libraries again, when I rebuild the main project? So I only have to do the resource-parsing / dexing / etc. for the modified libraries and possibly the main project, decreasing the overall build time in most cases.
Does this mean, that if I export parts of my large project into library projects which I reference from the main project, then I don't have to rebuild the already built (and not modified) libraries again, when I rebuild the main project?
Partially no, Android Library Project is not built directly, it is always built along with the dependent Main Project, when SDK compile/build the Main Project, SDK tools compile the Library Project into a temporary JAR file and uses it in the main project. whenever you re-build your Main Project, the referenced Library Project is re-built as a part of main project build life cycle, even though nothing changed in Library Project. Check out timestamp of the temporary JAR generated under your app-lib/bin folder for evidence, it always get changed every time yo build Main Project.
Quoting from official dev guide:
However, a library project differs from an standard Android application project in that you cannot compile it directly to its own .apk and run it on an Android device. Similarly, you cannot export the library project to a self-contained JAR file, as you would do for a true library. Instead, you must compile the library indirectly, by referencing the library in the dependent application and building that application.
When you build an application that depends on a library project, the SDK tools compile the library into a temporary JAR file and uses it in the main project, then uses the result to generate the .apk. In cases where a resource ID is defined in both the application and the library, the tools ensure that the resource declared in the application gets priority and that the resource in the library project is not compiled into the application .apk. This gives your application the flexibility to either use or redefine any resource behaviors or values that are defined in any library.
Android Library Project is different from regular java library project. where you can compile and build everything into and jar library once, and start import/use the class from reference jar dependencies in main project. Currently Android Library Project is designed on source-based mechanism, not compiled-code based library mechanism, as mentioned in this Android blog, although self-contained jar distribution is promised in future release (unfortunately not in neither r15, r16, r17 nor r18 yet).
Yes... The build system rebuilds what needs to be built unless you build Clean.
I wouldn't expect huge time savings here.
In my experience, the slowest step of compilation is actually the dexing of the output files, which can not be performed incrementally, so moving your code into libraries will not speed things up. Similarly, incremental compilation (when it works — it often doesn't with the Android toolchain) will work equally well with unchanged files spread over a bunch of projects as will unchanged files in a single project.
Of course, the best way to find the answer for your actual use case is to experiment on your actual code base. And there may also be code maintainability benefits to splitting your project up into independent modules.

Categories

Resources