Why do Google recommend copying libraries into your tree? - android

Google's instructions for using the Play Service API (for example) say:
Copy the /extras/google/google_play_services/libproject/google-play-services_lib library project into the source tree where you maintain your Android app projects.
Note: You should be referencing a copy of the library that you copied to your source tree—you should not reference the library from the Android SDK directory.
This seems ugly to me - why not reference it from the SDK directory? Is there some technical reason for this? Or is it so that you have explicit control over when it gets upgraded?

I'd like to point out that this is entirely a limitation of Eclipse, and it is indeed ugly.
The problem is that this library contains resources in addition to source code. Eclipse can only deal with libraries packaged as jar files, which, for the purposes of Android development, cannot contain resources.
So, in order for the library's resource to be compiled into the application, the library's source code, with the resources, must be added to your project.
If you move your build to Maven, and use an IDE that 'understands' Maven, then you can compile a library that contains resources as an 'apklib', and treat it as an external library, in a manner similar to a jar file.
The new Gradle-based build system is built on Maven primitives, but uses a different format for this, 'aar'. Hopefully, it will eventually also support apklib so that Maven builds and Gradle builds can inter-operate.
I just went through the exercise of converting an Android application to a Maven build, including the use of some apklibs. I can tell you that Eclipse with the m2eclipse plugin does not handle apklibs properly. Both IntelliJ and the new Google Android Studio (based on IntelliJ) do handle apklibs with no issues.

It's not about "Play Services Library" specifically. Just like any other libraries that the project makes use of, this library should be referenced from project's source tree.
In this case the external library is in the Android SDK directory and referencing from there is not a good practice too. So yes, it can be called "a technical reason".
Used libraries (Play Services library in this case) shouldn't be referenced from anywhere other than the project's source tree.

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

How to bundle the v7-appcompat support library into an application source code?

I'm writing an application which makes intensive use of the v7-appcompat support library on Android. At the beginning, I'd added the .jar file into the libs folder of my project, but that wasn't enough. Following the documentation (http://developer.android.com/tools/support-library/setup.html), I've added another project in Eclipse with the support library and I've set this project as a dependency for my app.
It works.
By now I've my code on Github, but because of this, the code on Github doesn't even compile "out of the box", cause it misses the dependency.
Is there any way to bundle the support library directly into the source tree so that everyone can fork the project, add it to eclipse and run it immediately bypassing the process of creating the library project as dependency?
I've many other .jar files into the libs folder and I would love to do the same with the support library.
Is there any way to bundle the support library directly into the source tree so that everyone can fork the project, add it to eclipse and run it immediately bypassing the process of creating the library project as dependency?
Not very well. Moreover, it would be an exceedingly bad idea, unless you are planning on maintaining your own fork of appcompat-v7 and having developers use your fork instead of the real one.
When you eventually switch over to Gradle-based builds, you can have the appcompat-v7 repository artifact as a dependency. Then, people using your build.gradle file to build the project will download the artifact as needed to satisfy the dependency.
I've many other .jar files into the libs folder
Those too really should be artifact dependencies. Admittedly, that's not readily possible with Ant or Eclipse builds. Maven and Gradle support this today, and Gradle is Google's long-term direction for project builds.
Support library is probably an Android library in the sense that it contains resources, assets, and has an own AndroidManifest.xml.
What happens f you merge the resources, assets, and Manifest entries of the Support Library with your project?

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.

Packaging a jar for Android

I have modularised some simple classes into their own project for reuse elsewhere. These classes typically contain only fields and accessor methods (i.e. nothing Android specific).
They are later packaged up using ant's jar task and stored in a Maven repository.
In an Android project, I've stored said jar file into a libs directory and added to the build path. On running the emulator however, I get a "class not found" exception relating to my package. Other third party libraries (such as GSon) are being picked up fine.
Are there any specific steps required to make a jar file compatible with Android? (This reply seems to suggest otherwise). How can I debug this further?
No as long as you do not need e.g. classes from javax.* that are not in Android. If I were you I would consider looking at using the Android Maven Plugin for your build though. Check out the morseflash example from the official samples collection. It showcases exactly your scenario.
You only need an Android library project if your going to be reusing Android components and resources. In your case, I believe you added the project to the build path, but I'm sure your not exporting it as part of the dependent project.
So open the project properties, open up the Java Build Path options and make sure that you have your JAR selected as an exported dependency in the Order and Export tab.
UPDATE
This is what your entry should read:
<classpathentry exported="true" kind="lib" path="libs/tlvince-dao-0.1.0.jar"/>
I've also forked an updated version of your gist.
This issue was a result of compiling the jar to Java 7. Android does not support Java 7 (yet).
Compiling to Java 6 bytecode by setting target="1.6" in ant's javac task solved the issue.

Android adding external libraries to project

I have a project that I would like to add external libraries to (and have them packaged with the application) but I am not sure it is happening. I read on this link:
https://developer.android.com/guide/appendix/faq/commontasks.html
how to, but they do not show up in any of the /data/data/project directories. Does anyone know how I can confirm that the libraries were in fact added to the project for use at runtime? Thanks.
If you include jars as External Jars under your project's Java Build Path, then the classes will be converted to Dalvik format and be made available in your project's classes.dex file, packaged into the .apk.
To confirm they are available, attempt to use something from the jar (Eclipse should suggest the relevant import when you first supply a class name) build and run the app and see if it works? If it works in development (e.g. from 'run' in Eclipse) then it will also work when the app is built in release and distributed as an APK.
You can also place jar under one of your source folders (perhaps creating special "libs" one) and adding it to build path.
Be warned - external libraries (which are compiled against some version or other of the libraries in a Java JDK) may sometimes have problems when running under android. This is because the Dalvik runtime has its own Java framework libraries, which provide most (but not all) of the Java APIs in the standard JDK Java framework libraries.
You should really recompile any external library against the android libraries so that you can see any missing APIs at compile time - and fix the issues there and then. Otherwise you run the risk of runtime errors under Dalvik when you call the external library from your Android app. See http://geekswithblogs.net/cyberycon/archive/2011/05/17/using-external-libraries-with-android.aspx
for more details.

Categories

Resources