How to Convert an Android Library Project to an External JAR? - java

I have an Android library project that has been working for me pretty well, but now I am interested in "converting" it to an external JAR.
How do I do that?
Can any Android library project be converted to an external JAR? If not, what are the restrictions or limitations?

Can any Android library project be converted to an external JAR?
Not right now.
If not, what are the restrictions or limitations?
If your library is purely Java code, with no resources, you can create a JAR out of the .class files, just as you would with regular Java.
If your library uses resources, you can still create a JAR as above. However, you will need to look up the R values (e.g., R.layout.main) via reflection or getIdentifier(), and your resources will not be packaged in the JAR but would have to be distributed separately.
In the future, the build tools should support creating distributable JAR files out of library projects, complete with resources. The current build tools do create JARs, but they are not designed to be distributed but are rather internal build artifacts at the moment.

http://developer.android.com/guide/developing/projects/index.html#LibraryProjects claims that you can't export these to an external JAR. Specific quote:
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.

Related

Including jar in project. And including Android Library project

I want to include a jar library in my project, but the library is really large.
I am not using all of the classes from that library, so when I compile my project, will all the jar content will be put in compiled project or only files (classes, etc...) which I am using?
And same question about Android Library Project: If I include the Android Library Project in my project and I am not using all of lib resources, will the compiler put all of Lib Project resources in my project or only resources which I have used?
i apologize if i don't understand the question, but maybe what you're looking for is this:
Selectively include dependencies in JAR
so here's the plugin
https://github.com/nuttycom/sbt-proguard-plugin
sbt proguard looks like it will cut down the unnecessary classes, so that your project will not be "heavy"
Although you may not directly be using classes within the JAR, you could be indirectly using them. Therefore, it would probably be unsafe to remove these classes from the jar-- unless you're 100% sure they're not indirectly used by the classes you are using.

Where do external libraries live in an APK?

I was wondering, when adding a external jar to a android project, where do they actually live inside the APK package? I can't seem to find them.
Since Java usually loads classes at runtime as needed, it weirds me out that they don't seem to be in the distributable.
Is dex different? are these static builds?
If by "external libraries" you mean "library projects", the answer to this question can be found in the documentation:
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.
The separate .jars that you are referring to don't exist; they are merged into a single .apk at compile time.

Benefits in Android to importing a library internally vs externally

Post ADT 17, non-Android libraries need to be included either in the "libs" folders of the project or exported via the "Order and Export" tab in the build path. What's the difference (if any) between importing a library externally:
And internally:
Is there an advantage to importing a library in a way that it is included in the "Android Dependencies" group?
How do you add external jar dependencies into your Android project's build path (internally or externally) make no difference on the actual build process (more specifically at compile and dex step), all it does is to tell build process where to looking for the required jars at compile and dex step.
The Android Dependencies element shown in Java Build Path - Libraries window is just another abstract layer that ADT plugin used for managing/grouping jar dependencies. where your external jar files (in your case android-support-v4.jar) appears (inside or outside Android Dependencies) in that window makes no difference.
Since r17, dependencies management has been much improved, and it is recommended to use libs/ directory store all jar dependencies (refer to you internal way), which is considered as a automation approach (as ADT plugin becomes more smarter now), see Revisions for ADT 17.0.0:
New build features
Added feature to automatically setup JAR dependencies. Any .jar files in the /libs folder are added to the build configuration (similar to how the Ant build system works). Also, .jar files needed by library projects are also automatically added to projects that depend on those library projects. (more info)
However, you can still use the old way (refer to you external way) if you prefer, which is considered as a manual approach (as ADT plugin was stupid before), see Recent Changes‎ for r17 Release:
Important: If you are still referencing jar libraries manually instead of putting them under libs/ be aware of the following:
If the project is a Library project, these jar libraries will not be automatically visible to application projects. You should really move these to libs/
If the project is an application, this can work but you must make sure to mark the jar files as exported.
Is there an advantage to importing a library in a way that it is included in the "Android Dependencies" group?
Automation vs. Manual from dependency management perspective, automation is always considered as more errorless than manual in the world of computer science.
The number one, show stopping, 'I can't believe they didn't test this', disadvantage of putting external jars in the libs directory is that you can't set the javadocs location for them, as the option shows as 'None (non modifiable)'.
Hence I still use Export option in build properties
It has to do with library dependency management of Android. for details see http://tools.android.com/recent/dealingwithdependenciesinandroidprojects
From the Eclipse FAQ
An internal resource resides in some project in the workbench and is therefore managed by the workbench; like other resources, these resources can be version managed by the workbench. An external resource is not part of the workbench and can be used only by reference. For example, a JRE is often external and very large, and there is no need to associate it with a VCM system.
So, quite simply, if you want to be able to manage a JAR as part as the project, exposing it to SCM and such, then treat it as a internal resource otherwise, treat it as a external resource. It will not make any difference in the APK produced in the end, its simply a eclipse thing.
If you want to avoid creating a copy each time you want to use your library, treat it as a external resource. But, can I suggest you look into maven and the android maven plugin, maven has a bit of a learning curve (especially if you are used to "make" or "ant" style build scripts), but it is very much worth the effort.

A jar inside another jar in Android (Java)

I have a library project that uses a jar ("httpmime-4.1.3.jar"). I'd like to take the jar generated by that project and use it in other projects but when I use it in other projects and one class of the "httpmime-4.1.3.jar" is required the app crashes with a NoClassDefFoundError.
How can I solve that without having to add the "httpmime-4.1.3.jar" to all the projects reusing the library? Thanks!
You might consider using something like maven for dependency management. With maven, you specify the libraries that your library project depends on (httpmime). Then, any project that depends on your library will automatically recognize that it needs to download and put the httpmime jar in its classpath as well, and you don't have to worry about manually copying files around.
Edit: I just saw that you're specifically looking at android development. Here is a plugin with a nice getting started guide for using maven with android.
You have to add it to the classpath. You can't include it in another jar.

Deploying Java Files

What are the best practices (and enabling tools) to deploy Java standalone applications along with any required jar dependencies, config files, and launch scripts?
Are there any Maven plugins that easies publishing binary releases, so that users don't need to use maven for example?
Are there any Maven plugins that easies publishing binary releases, so that users don't need to use maven for example?
Use the Maven Assembly Plugin to create a binary distribution as zip/tar.gz/tar.bz2 of your project. This plugin is extremely flexible - at the price of some complexity - and you can do almost anything you want. Then deploy (in the maven sense) the produced artifact, upload it somewhere, etc.
As for dependency, I just use maven dependency copy plugin and copy all dependencies into a ./lib folder, and supply a launch script that uses the class path wildcard (that way you can change your dependencies as much as you want and don't have to change the launch script). As for configuration files, I put it in a ./config folder and again include it in my app's classpath in the launch script (The former admittedly only works for > java 1.6).
So in the end almost all my app has the following structure:
mystuff.jar launch.sh
./lib
./config
Then I'll just zip up the whole thing and give it to my users. The whole process is probably easy to automate using maven, but I confess that I do it by hand :p
If you prefer and the licenses permit, you could also just bundle all dependencies into a single jar (with expanded dependencies inside) using the assembly plugin. This tends to make the jar bulky and giving the users an updated app. more difficult. Also I had issues with it several time because of class files getting overwritten or something so I personally stick to the ./lib folder.
There's launch4j, which, if you can get it to work, will bundle up a Java app into an executable for your platform.
If your deployment target supports RPM files, I strongly suggest you investigate the rpm-maven-plugin. It allows you to easily map your project artifacts , including dependencies, to a RPM package.
I've been using it with great success to medium-scale application deployment.
You can use Oracle's ant or maven scripts:
http://docs.oracle.com/javafx/2/deployment/jfxpub-deployment.htm
The above will not only compile your code and create jar files, but it will also create binary executable (windows exe file or Mac app file). It can also create native installers. In addition it lets you include JVM with your distribution so the end use doesn't need to install Java.
Take a look at the Appassembler Maven Plugin. You may also want to combine it with the Assembly Maven Plugin.
Use the appassembler plugin to generate a set of "programs" by specifying executable names and main classes. You can also have it prepend and create an etc directory in which you can add configuration files.
If generating the directory with the start-up scripts and directory of binary files isn't enough, you can use the assembly plugin to copy over additional files (say your configuration files) into the appropriate directory and/or package your application into an archive.

Categories

Resources