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

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.

Related

Migrate project from Eclipse to Android Studio with more projects depending on a single library

I have an old eclipse android workspace which has the following structure:
one library project which has all the code and default graphics and resources
other projects which depend on the library project, but with different package names, different strings.xml and different graphic resources.
Basically what this means is that all my code is in the Library Project, and all other projects are really just different apps, based on the same code, but looking differently with different names
All these were in one Eclipse workspace and now I need to update the project, so upgrading it to Android Studio sounds like the best way to go.
The easy way is to hope that export works for your case. I battled with Eclipse->Studio migration for weeks. I had exactly that situation - one common project and other apps on top of it. Studio will just convert your common project into an Android library module, and other 'app' modules will be converted into Android app modules. Check out this answer: https://stackoverflow.com/a/22797387/2102748
When you're migrated, you should look to move your source files from the ant-style hierarchy to the gradle-style hierarchy. There is a lot of content for that here: http://tools.android.com/tech-docs/new-build-system/user-guide
Android Studio will also ask you to replace .jar libraries it knows about (like appcompat, google-play-services, etc) with gradle dependencies - do it. Life becomes so much easier.

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

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.

How to create multiple Android apps from one code base

I have an Android code base which uses APIs with settings to get different data for several apps. All apps use the same code base but with one or two design tweaks. So how do I re-use the main code base without having to copy the whole Android project each time?
iPhone uses multiple targets in the same project which works well. If android cant do this do I need to compile binaries of the code base in one project and then import into each new app project? If so how? I'm using Eclipse and am an intermediate Java developer.
Any help much appreciated!
Doug
Check out "Working With Library Projects" from the Android documentation. This should be just what you're looking for: http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject
The current way to approach this issue if you are using Android Studio with Gradle is by using Gradle, Build Type + Product Flavor
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
Build Variants
One goal of the new build system is to enable creating different versions of the same application.
There are two main use cases:
Different versions of the same application
For instance, a free/demo version vs the “pro” paid application.
Same application packaged differently for multi-apk in Google Play Store.
This new concept is designed to help when the differences are very minimum. If the answer to “Is this the same application?” is yes, then this is probably the way to go over Library Projects.
Note: This answer is basically obsolete now that one can create .aar libraries with resources. It still works, though, and there may be times when the portability of a .jar is desirable, so I'm leaving it here.
Blumer's answer is a good one, and you should definitely look into Android's idea of library projects. However, there is another alternative. If you have a module that contains only Java code, but no resources of any kind (images, layouts, etc.), you can compile it to a .jar file separately and use the resulting .jar in multiple application projects. It works like this:
Create a new Java project in Eclipse (not an Android project) and move the source code of your module there.
If your module references any classes from the SDK, you'll need to add the Android SDK .jar to the project's classpath (Project > Properties > Java Build Path > Libraries > Add JAR).
When your module is ready to use, bundle up its .class files into a .jar. You can do this manually, or you can look around to figure out how to get Eclipse to do it for you.
Copy your module .jar file into the "libs" directory of your app's main project.
Add the module .jar to the project's classpath (again, Project > Properties > Java Build Path > Libraries > Add JAR).
Now you should be able to build multiple apps using the same .jar, while maintaining only one copy of the module's source code.
Depending on your particular situation, this may or may not work any better for you than the standard Android library mechanism. But it's worth considering as an alternative.
The Android documentation recommends another approach if there aren't too many "different APIs" used.
The idea is to use reflection instead of making direction references to the code. Make sure to use optimized reflection instead of lookups every time.
References
http://developer.android.com/training/multiple-apks/api.html
http://developer.android.com/google/play/publishing/multiple-apks.html#ApiLevelOptions
You might want to consider using a source control system like Subversion (or GIT). Keep your most feature complete version in the trunk, and make branches for your separate versions that use different data sources or require minor layout changes, etc.

Self-contained test library project cannot find the library classes

According to this SDK guide, unit-testing a Library project can be achieved by creating a standard application project, reference the Library project and then instrument the application for unit testing.
However, when I do this and launch the test application I get the message
No tests found with test runner 'JUnit 3'.
I'm using Eclipse and the Android ADT plugin, all latest versions.
Note: the projects compile just fine. The test project also installs fine to the emulator. But in the console I can see that it looks for <library>.apk, which of course doesn't exist since I'm compiling this as a library into the test project.
Anyone got this to work? And if so, what is the trickery here?
Update: after discovering and fixing a problem, which was actually including the test classes (!), the test runner now can find all tests. But, all the tests fail with the following exceptions:
java.lang.NoClassDefFoundError: <nameOfClassInLibraryProject>
nameOfClassInLibraryProject are classes defined in the library project. These classes should be compiled into the test project, and indeed, everything compiles just fine. But when running the test project, the runtime doesn't seem to find the library classes.
After much fiddling and wasted time in Eclipse I have managed to get Android Library projects to work.
According to the Working with Library Projects article:
Instead, you must compile the library indirectly, by referencing the library from a dependent application's build path, then building that application.
The problem was that I interpreted this to mean that the library project should be added to the Projects tab in Java Build Path. Doing this makes the test project compile since the library code is obviously available to the compiler. But since the library is not compiled into a .jar or .apk in itself, the library classes are never deployed to the device.
The solution is to not add the library project to Projects, rather on the Source tab, add the library /src folder using the Link Source... button. And yes, it is the library src folder, not the library project root, that must be linked into the test project.

Categories

Resources