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.
Related
Recently, I ported my existing Android project from an ancient Gradle version to Gradle 6.6 and Android Studio's Gradle plugin 4.0.1. This project uses an external native library (.so file) that gets used in the Java code via JNI. This .so library has a dependency on libc++_shared.so because it is written in C++.
I realized that if I just copy the .so file into the corresponding platform folder (arm64-v8a, armeabi-v7a, x86, x86_64) within the jniLibs Gradle packages it "properly" into my .apk file.
By "properly" I mean that it automatically adds libc++_shared.so, which my library has a dependency on, as well as my own library to the .apk file. In addition, if I additionally set jniDebuggable to true in the build.gradle file it will also add the gdbserver library which is required to be able to attach the native code debugger.
Now, this is exactly what I want. The problem is that I cannot find any documentation that describes this behavior. The best source I could find is this but it does not mention anything about dependencies being packaged automatically. So, I don't know whether that is an officially supported way of doing things.
I suspect that there is a part of Android's Gradle based build process that automatically analyzes the files in the jniLibs folder and acts accordingly. It would be great to know a bit more to be aware what is really going on.
Does anyone have a reference that confirms my above observations or know which Gradle task (or whatever) accomplishes this? It would also be good to know in which Android Gradle plugin version this behavior was introduced.
Edit:
This answer to another SO question led me to the Android source file https://android.googlesource.com/platform/tools/build/+/master/builder/src/main/java/com/android/builder/internal/packaging/Packager.java
which seems to be the code that packages the .so files and gdbserver into the .apk file. But I have no explanation why libc++_shared.so gets packaged as well.
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.
I wish to back port the Android RTP APIs introduced in version 3.1(Honeycomb) to earlier versions. I downloaded the source of version 4.0 and found that it these APIs had both java and native code. In order to build the native code with the NDK, certain shared libraries are required.
According the Android.mk file, these are libnativehelper, libcutils, libutils, and libmedia. Though the source of all of these are present in the source code, building them was difficult. Each required many other shared libraries. For eg, libmedia requires these shared libraries: libui, libcutils, libutils, libbinder, libsonivox, libicuuc, libexpat, libcamera_client, libstagefright_foundation, libgui and libdl.
So my question is, is there some way of obtaining the original 4 shared libs? Does it involve building the entire source?
Say I need to build a piece of native code which is going to use standard Android shared libraries such as libutils, libcutlis, libmedia. I would perform following steps:
Install AOSP repository with target version.
Add my source code to appropriate directories under ./frameworks/base. In your case it might be easier to create a separate folder and put proper Android.mk of course.
You might get compile errors if required functions from those standard shared libraries are not present in the previous version.
When you build the code as part of AOSP it will build required libraries and link them for you automatically.
P.S. To accomplish that you're better to use a Linux-based build host.
using cygwin terminal, build native part i.e. jni folder. To build using cygwin, goto jni folder using cygdrive command. Then type ndk-build. After successful completion, shared libraries i.e. .so files will be created in libs folder.
I can understand your problem, you can pull the libraries from /system/lib of device or emulator. But you need a system permission. But you can do it by installing application.
Otherwise build your source code on linux platfor. Building process is very easy, just using 2 or 3 command. First time it is needed long time to build. After that you need very short time to build, it will build only according to the timestamp of modified code.
Please have a look here
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.
I want to use geotools(8.0-M3 currently, could be also 2.7.3) library in an Android app, using eclipse. (win7 prof, 4gb ram)
But the build process crash, and i get following error
Unhandled event loop exception Java heap space
The java heap space problem should be solveable, but it seems there is more. (3gb should be enough, isn't it?)
My final target is to be able to request a postgres postgis db on geoserver by OGC "web feature service" and "web map service".
I already set the eclipse ini to
--launcher.XXMaxPermSize
128m
--launcher.defaultAction
openFile -vmargs
-Xms40m
-Xmx3700m
Geotools require more than android libs (in compare with jre6 (1.6.0_24)) provide.
-> So I copy the whole jars from jre6 folder plus jts-1.8.jar plus the geotools jars into a seperate (win) folder. (Maven(not in use in this case!) by itself load jts-1.1.3 lib, does it make any difference?)
The whole jar folder has a size of nearly 80Mb.
-> Create a new folder in eclipse android project struture.
-> import the jar files from the win folder into eclipse
-> add the jars to the project build path (which should port java to dx)
(After a long time (days) of trial thats the only way i know, to provide all neccessary classes to the app. At least eclipse doesn't mark anything missing).
After the compilation crased the eclipse console output:
Dx warning: Ignoring InnerClasses attribute for an anonymous inner class.....
for several classes. Probably because of the jre lib.
What other options to provide geotools the necessary java libs in my android project do i have?
Or do you have any idea of the trials i mentioned below?
PS: Android books recommend to copy just the missing classes (and their dependencies Haha) out of the jar files..... (i will probably better write them new)
I already tried using the maven plugin. Which works well in a pure java project using geotools or as it take care of an android project as long i don't use geotools.
If maven include an android project using geotools the libs are loaded by maven but then android say something like "R class modified manually"...
(what i can't revert, or recreate)
Is there a way to copy the maven dependecy library (which should consist of what i need) out of the eclipse project. (I thought i could copy the jars out of the win repository folder, but that include also to much others jars).
Android provide a "Java Native Interface" which allows to use C++ or other libs. Would it be an option to surround the porblem of missing/crossing libs (I have no experience of JNI yet)?
The app code is pretty short, if it help you i can paste it.
What other options to provide geotools the necessary java libs in my android project do i have?
If you need classes that are part of a standard Java distribution but are not in Android, you are out of luck, other than to rewrite geotools to avoid needing those classes.
If you need classes that are part of other third-party Java libraries, add those third-party Java libraries to your project.
From a brief examination of geotools, I suspect that it will need to be substantially rewritten to run on Android.
PS: Android books recommend to copy just the missing classes (and their dependencies Haha) out of the jar files
My books do not. Any author advising this needs to have their head examined.