Can someone guide me on the correct placement of where *.so files are supposed to be housed for a gradle/android project?
I have them in:
project->app->src->main->jniLibs
and the assets, java, and res folders are siblings to it in main as well but they don't seem to be included when the APK is built causing an 'UnsatisfiedLinkError'
EDIT
I have looked at:
Include .so library in apk in android studio
and have tried changing the director to both libs and lib with no luck.
UPDATE 1
The APK de-compiled now shows the *.so files under /Lib and I have them under project -> app -> src -> main -> jniLibs -> armeabi and that is their architecture but I am getting an UnsatisfiedLinkError when calling a method from within the native library although it seems to get past the System.loadLibrary call in the static constructor without showing an error
*.so files are included and shown in decompiled APK now...hitting another issue which I posted here: UnsatisfiedLinkError when calling method from native library although System.loadLibrary seems ok
Related
i have looked through all the other posts here about this subject but none of them helped me.
i am using a third party SDK (oovoo) and it contains a .jar file and .so file (armeabi-v7a)
as stated in allot of places, i put the .jar file in the libs folder and the armeabi-v7a folder (which contains the .so file) in a folder named jniLibs inside src/main
after building, when i unzip the .apk i see a folder named lib and inside it a folder named armeabi-v7a which contains the .so file
yet i still get this exception:
java.lang.UnsatisfiedLinkError: Native method not found: com.oovoo.core.ClientCore.VideoChannelPtr.nCreate:(Ljava/lang/String;)J
why cant it reach the implementation?
if it is in the lib folder in
the .apk does it mean it will for it at runtime?
thanks allot!
android studio version 0.8.6
gradle version 1.12
oovoo version 1.2.4
To answer your questions specifically :
It can't reach the implementation because at runtime, when the java environment tries to load a native method named java_com_oovoo_core_ClientCore_VideoChannelPtr_nCreate with the prototype int (string) it doesn't find such a method loaded. This can be caused by the following :
the .so library isn't loaded by the time you called that method , hence java doesn't know about it (so it's your mistake, you called the functions in wrong order)
the .so library doesn't export such a function, which means you have no chance of fixing this
the .so library loaded at runtime by the phone requires a different architecture besides armv7s. Be sure your device is armv7s.
the folder in which the Android system is looking for native libs is different than you expect. I know this was an old issue, so create in your apk, in your lib folder both "armeabi-v7a" and "armeabi" , and copy that .so file in both
Regarding your 2nd question, yes, if you have the lib inside the apk you will have it at runtime.
I've made an android library project that uses some native libraries.
I've made the jni wrapper and put the native libs (.so) in the libs// folders. The native libs are compiled using cmake, for armeabi, armeabi-v7a, x86 and mips.
I export this project to a jar and put this jar into a "normal" android project. I then export this project to an apk and can see that my libs are bundles into it.
However, when i install the apk, the libs corresponding to the device are not copied into /data/data/com.my.app/lib and obviously, running the app complains about not finding the libs (UnsatisfiedLinkError).
I've search through SO and everywhere i can but found no answer that solved my case.
i'm using Eclipse, btw
Thanks for your help
UPDATE
OK, i've read the doc in the ndk and seen the examples, and unfortunately, i can't see the solution.
The ndk build the c code into shared libs and places them into the appropriated location in the project. But it doesn't generate anything that says that the libs must be installed with the apk.
My goal is to provide an android library (so a jar), that can be included within an android application. I don't see the real difference between what i'm doing (compile the c libs using cmake and package the jni and java compiled classes into a jar) and what is done with android.mk
If you see what i'm missing, feel free to tell me (even if its obvious).
thanks
UPDATE
i've made a dirty hack: in the libs folder of my application, i've put the jar file containing my classes and my native libs and a copy of the .so files for each arch. Suprise, the libs are no installed in /data/data/com.me.myapp/lib
It seems to confirm that it's a packaging problem.
I export this project to a jar and put this jar into a "normal"
android project. I then export this project to an apk and can see that
my libs are bundles into it.
The issue is that the Android packaging system doesn't handle with binary assets in JARs. For your application project to find and include the generated .so files, you need it to reference the library project as an 'Android library project':
Did you call ndk-build command?
See description below for details.
http://developer.android.com/tools/sdk/ndk/index.html
You can build the shared libraries for the sample apps by going into /samples// then calling the ndk-build command. The generated shared libraries will be located under /samples//libs/armeabi/ for (ARMv5TE machine code) and/or /samples//libs/armeabi-v7a/ for (ARMv7 machine code).
I'm trying to build an app using a library packed in a JAR file.
When I call one of the functions I get this error:
Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing thelibrary.class
I've check the source code of the library and I think it crushes when loading some .so files ( System.loadLibrary("usb-1.0");
those files do exists in the JAR project under libs/armeabi (libusb-1.0.so)
I guess the .so files are not packed with the JAR, so how do I get them to be found in my project ?
(tried to copy them to libs/armeabi but the same exception is thrown....)
I do not get any link / build errors....
Thanks.
An ordinary JAR file will not work for distributing something that is dependent upon an Android NDK-compiled library. However, an Android library project can also distribute an NDK-compiled library.
but the real problem is that my app is going to be a library as well, and I don't know if I can make it a library while it is using other libraries
Assuming that "make it a library" == "make it an Android library project", this is fine, so long as projects attempting to use your library project also have access to the other library project.
I'm trying to build a medium-size project in Eclipse. It consists of main app project and two Android libraries. Everything worked fine until I added a very simple JNI library to main project.
When I run the app on device I see this exception in LogCat:
01-11 17:19:01.421: E/AndroidRuntime(26569):at
java.lang.Runtime.loadLibrary(Runtime.java:429)
Couldn't load xxx: findLibrary returned null
I googled around for similar problems and I believe that I did everything correctly:
The only .c file and Android.mk file are placed in the 'jni' folder
I build the library with ndk-build tool
The .so library is correctly placed in the 'libs\armeabi' folder
I see that the resulting apk file does indeed contain my native library
When I create a test project and link to the very same native code - it works fine. The problem persists in the main project. I already tried to create Eclipse project from scratch but it didn't help
I use Android SDK Tools v.16
Can anyone please help me with a suggestion?
Thanks!
Ok, after two days fighting the Android SDK I managed to solve my problem. Here's some explanation just in case it may help anybody else.
My previous project structure:
Android Lib1 project (with it's own jni code)
Android Lib2 project (depends on Lib1)
App1 project (depends on Lib2)
App2 project (with it's own jni code; depends on Lib2)
The original problem has been seen when I tried to load jni library in App2. I still don't understand what was preventing the runtime from finding the jni in the App2.
However the solution was to remove the Lib1 project from the workspace and add it as JAR file to Lib2 and both Apps. Now I'm finally able to use load the jni lib in the App2.
I have built a dynamic library in android using android build system. This library provides jni interface for functions inside it. Now I want to include this library in an application (.apk). I am using eclipse for application development. Now, how can I use the prebuild dynamice library (.so) in my application ? I tried putting it in a lib folder in my application but it is not working.
Any pointers are appreciated.
I am not using ndk to build my .so.
Since you write 'so' I think you're using NDK. If you're using NDK I don't know the answer.
If you're using the "Java" SDK, then in your library project go to Properties -> Android, and Check "Is Library". In your "apk" project, go to Properties -> Android -> Add . And your Library project should be available.
Also, any Library added in the "Java Build Path" Menu (again, in project properties) should be available in the APK in the end.
I know it's slightly old, but have you checked in the built APK to see if your .so library is there? Should be in the libs/armeabi folder.
Also, your .so file should be in lib/armeabi folder in your eclipse solution. I'm guessing the armeabi bit depends on which processor your .so file is build for.
Also, I know that if your library isn't called lib[name].so, it won't get copied when the apk is installed on the device. So:
libfoo.so copies
foo.so doesn't copy
foo.so doesn't copy
Also, you can use DDMS (its a view in eclipse) and it's file explorer to see if it's been copied to your device. It should be under data/data/[packagename]/lib.
Hope this helps a bit!
Andy.
I hit this same problem while building Qiqqa for Android. Under your eclipse android project, make sure you have a libs directory (not that it is plural libS not singular lib). Inside that create the armeabi/etc subdirs with their respectibe .so files.
Then when you build, eclipse will automatically pick up this libs directory and create the corresponding lib in your apk. System.loadLibrary("XXX") will then resolve to libXXX.so on your correct architecture...
Cheers,
Jimme