I am working on an android library, and wish to export a JAR file that I can distribute for others to use in their apps. I don't want to distribute the source code as it contains details on posting to my web server.
I have tried using the JAR file that is created in the bin directory and copying the jar file to my project and referencing it within my project and ticking the export button.
When I try and run my project referencing the library that I've copied, my app throws an exception with NoClassDefFoundError. I've done some Googling and everything I have found suggests you have to provide the source code and let the user import into their IDE and then reference that project into their app which I don't want to do. It must be possible as other companies provide JAR files for libraries that can be included.
Thanks for your help.
I don't want to distribute the source code as it contains details on posting to my web server.
Bear in mind that anyone who wants to can get that data out of the JAR.
It must be possible as other companies provide JAR files for libraries that can be included.
AFAIK, this recipe still works:
Create an Android library project, with your source code, resources, and such, and get it working
Compile the Java source (e.g., via Ant) and turn it into a JAR file
Create a copy of your original Android library project to serve as a distribution Android library project
Place the compiled JAR from step #2 and put it in libs/ of the distribution library project from step #3.
Delete everything in src/ of the distribution library project (but leave the now-empty src/ directory there)
Distribute the distribution library project (e.g., ZIP it up)
This effectively gives you what you see with the Play Services SDK -- a library project with no source code, but instead a JAR in libs/, along with the resources and such.
I will be reconfiming this recipe tomorrow and will try to remember to update this answer if I find that it needs adjusting for the current crop of tools.
And the new Gradle-based build system supports the AAR package for distributing libraries and such, though I have not played with this yet.
UPDATE
This recipe works, so long as the library project does not itself have dependencies upon another JAR or library project. In those cases, things seem to get messed up in the build process -- everything can compile, but class references from the dependencies cannot be resolved at runtime.
Did you try putting your jar file in libs folder?And if you are exporting a jar library for android be sure it has no /res folder. As you know you can't reference to your res folder from a jar therefore you have to use library project to reference your res folder (drawable,xml,ect...)On the other hand you cant make your code safe (the part you say about posting to your web service) by using it as jar since it is so easy to retrieve by reverse engineering. you better use some encoding (like base64 or any algorithm that bouncycastle provides)
Related
if I have a project with many library projects linked, could I improve build performances by packaging each of them in an AAR and including it in the main project ? Or this will not make any difference since that when the compiler need to assemble the apk it need to package everything together anyway?
Thanks to any one who will give me some clarifcation about performance differences between the 2 approach
I don't think you will save any build time by wrapping an existing .jar file into a .aar file and using that instead of the original .jar file.
As this SO post notes, .aar files are basically just zip files which may contain a jar file and some android resources.
Also, because .aar files are not precompiled into Dalvik byte code, the build process for your apk file must still carry out that step at least once. So, you won't save dexing time just by wrapping the .jar file into a .aar file either.
If you build a typical Android Studio project (with some Android library dependencies specified in the gradle build file) you can see the directory underneath app/build/intermediates/exploded-aar where these files have been unzipped. That work must still be done by your build machine even though you are using a .aar file.
Finally, as you pointed out, the .apk packaging work must still be done at the end of the build.
I believe the Library projects (which you are using) is the best way to go because of two reasons:
The library project gives the direct access to the code base of the libraries which can be compiled and packaged together with the main app code
In case, multiple .aar files are referenced within the project, then during the apk creation the unpacking, merging of resources and Manifest file will increase the build time.
I'm building and Eclipse to make an Android library I want to distribute to developers.
TedLibJni:
It uses the Android NDK and so it compiles down to a .so file.
TedLibJar:
It also has a Java interface that binds the then extern'd calls in the JNI, so it has a Jar library associated with it.
TedDroidApp:
The concensus is that I need to manually copy both TedLibJni.so and TedLibJar.jar to lib/armeabi of this App for it to be used.
Question: Is there any way that TedDroidApp can pick up the externally located .so or .jar files? It seems crazy that I would have to manually copy and paste these files accross each time I iterate them.
Use an Android library project for the JNI code and the JAR. You can then attach the Android library project to other projects. With the new Gradle-based build system, you can package the library project up as an AAR and obtain it from an artifact repository as well.
CWAC-AndDown, my wrapper around the C hoedown library, works this way.
How should external libraries be included into Android projects?
I see this documentation from Google:
http://developer.android.com/tools/support-library/setup.html#libs-with-res
...which says they should be kept outside the source tree for the project, and referenced as dependencies.
The guide for Facebook libraries says the same thing:
https://developers.facebook.com/docs/android/getting-started/facebook-sdk-for-android/
What about when the project is going into source control, and will be worked on by multiple developers? Is it possible to be sure other developers will have the correct versions of libraries if they're not included in source control?
It seems as though it might be better to check in the whole tree of these external libraries under say an "external" folder in the project and then reference them as libraries from there? The above links don't say this is wrong, but is there any reason not to do that?
I could not find anything against this approach, but maybe my search skills are off.
Thanks!
You have basically tree options (referring to git):
Putting the source or binaries into your git repository.
You can create/clone extra repositories and link these as submodule into your main repository.
Use gradle/android-studio to maintain remote binary dependencies.
In my opinion, option 3. is the best. It speeds up build time and reduces the date saved in your internal repository. Referencing most open source projects, googles libraries and even the Facebook API is just a one liner in your build.gradle file.
For internal libraries or anything not uploaded to some maven repository, you can create a local maven repository and link that.
And in the end, you have the option 2. to create a library submodule within git and gradle to handle it efficiently.
If you want to stick to eclipse + ant, try 2. first.
At least ant will work out of the box for building all things.
Setting up eclipse is a bit more difficult but can be done.
Option 1. is easy to implement, but It might get messy at some point.
Copy jar file in android project libs forlder and right click on jar file and click on bulid path-> add to build path.
If you want to add jar file then copy your jar file and put in to libs folder, and if you want to add external library then import your library project go to project properties and select android tab and add external library with add button.
I have a project that uses some resources.I want to create a library from it and publish it.I create a jar file with export option of eclipse,but it did not work.Then I search the we b and it seems that way works if and only if project does not use resources.But I saw this post.Here CommonsWare saya there is a way to create a jar file from a project that uses resources.But that answer has two link that do not open any page on the web and I could not test CommonsWare's answer.So my question is:
Is there any way to create jar library file from project that uses resources?
Note:
I read docs that say:
If you have source code and resources that are common to multiple
Android projects, you can move them to a library project so that it is
easier to maintain across applications and versions.
But as I said before,I want to publish my jar and docs say we can not create jar file from library project.And so I can not publish it.
Here CommonsWare saya there is a way to create a jar file from a project that uses resources.
Not in that answer. You can tell that by actually reading the answer.
But that answer has two link that do not open any page on the web
Sorry, Google reorganized their site and broke the original links. The answer has been updated with current links.
Is there any way to create jar library file from project that uses resources?
No.
You can create an Android library project that includes a JAR instead of Java source code. AFAIK, this recipe still works:
Create an Android library project, with your source code, resources, and such, and get it working
Compile the Java source (e.g., via Ant) and turn it into a JAR file
Create a copy of your original Android library project to serve as a distribution Android library project
Place the compiled JAR from step #2 and put it in libs/ of the distribution library project from step #3.
Delete everything in src/ of the distribution library project (but leave the now-empty src/ directory there)
Distribute the distribution library project (e.g., ZIP it up)
And the new Gradle-based build system supports the AAR package for distributing libraries and such, though I have not played with this yet.
This seems to be a common issue when exporting jars with Eclipse. Now, my context.
I'm attempting to write Java plugins to use in Unity applications. When I did a simple plugin with no external libraries (except the classes.jar so I can call a UnityPlayerActivity), it worked pretty well. "Now, let's use some utils libraries". So I wrote a plugin which uses Jackson libraries to parse and process JSON data, so I can serialize it to a Java object, or just pass RAW data, then build a Unity (C#) object.
I add the libraries directly from the file system to the 'libs' folder (copying the .jars, not linking them), add to build path, check every one in the Order and Export, clean and build, and export to JAR file (not runnable, but simple JAR file). Then, I add my new .jar to Unity Assets/Plugins/Android folder, then build my .apk. As soon as the game starts, I get the classic NoClassDefFoundError because of a constructer using a Jackson class. Checking the .jar contents, I find that Jackson libraries are, indeed, exported and within the 'libs' folder, but still it won't "find" it. The error will be thrown by the main thread, thus the application will crash.
I'm using ADT with API 17, so the libs folder must be named 'libs' (even Eclipse does create this folder when creating a new Android project), JRE 1.6 and Jackson libraries ver. 2.2.0. Already followed a lot of questions here, but none of their suggestions has worked for me.
Any pointers here? Has the Android API version anything to do here? Is there something I'm not doing?
Thanks in advance.
I'm quite new to Java, but as far as I can tell when you use an external JAR file it is dynamically linked. In other words, it stays independent - it is not merged into your library.
This was obvious in my case: The external library I used was Google Analytics. Its JAR file, libGoogleAnalyticsV2.jar, is 126 KB. After I added it to my libs directory and built my library I got an output JAR file of only 2 KB...
My solution was to copy the external library JAR file to Assets/Plugins/Android, together with the JAR file I created.