I've been struggling with this for a while, and although I have found many having similar problems, their fixes don't seem to work for me. Perhaps I am misunderstanding something though, regarding of where the shared library files go after installing an APK.
Setup: Android, using a build.gradle file, and CMakeLists.txt since I want to run some C++ code using JNI. I followed the tutorial basically from https://developer.android.com/studio/projects/add-native-code, along with other pieces here and there from other websites.
My C++ code works correctly (it only returns a number). The APK generated can be unzipped, and I see all the .so files under the lib directory. Inside /lib there are four directories, each one for a different arquitecture, including my target (ARM). However, when I install the APK and try to run my C++ code portion, it returns an unsatisfiedlinkerror with the message saying "We looked for your .so file on nativeDirs under /system/lib and /vendor/lib, but we didn't find it)."
Now, if I instead push the .so file from the unzipped APK, into the location they mention, everything will run correctly (so at least my code is compiled correctly). Am I misunderstanding something? I was also reading that it appears that the .so files are not extracted from the APK anymore, but still, it's not finding it. I actually can't find the .so file in the system at all, but again, if I extract the APK it will be there.
My CMakeLists.txt simply have the parameters based on: https://developer.android.com/studio/projects/configure-cmake
cmake_minimum_required(VERSION 3.4.1)
add_library(native SHARED
nativeCode.cpp)
target_link_libraries(native
android
log)
I'm loading my library as:
static {
System.loadLibrary("native");
}
My questions are:
First of all, where should the .so files exist in my device after installing the APK.
Should I specify in any way the location of where the .so files should be under CMakeLists.txt?
If I need to specify a path for the app to look for the .so files, where should this be?
Thank you for your help!
i'm answering your question one by one...
QUESTION : First of all, where should the .so files exist in my device after installing the APK ?
Starting From Android M, it supports uncompressed native libraries in APKs, which allows the platform to read the native libraries directly from the APK without having to extract them.It have the flag android:extractNativeLibs which is default false. This is why you don't see them in the "data/data/packagename/lib/" directory if you're testing on a device on Android M or later.
Ultimately for testing purpose you can use android:extractNativeLibs="true" in Application tag of AndroidManifest.xml, to see in "data/data/packagename/lib/" folder.
<application
android:extractNativeLibs="true">
...
</application>
QUESTION: Should I specify in any way the location of where the .so files should be under CMakeLists.txt?
Considering your nativecode.cpp in rootPath/app/src/main/cpp/nativecode.cpp, and your CMakeList.txt under roothPath/app , your CmakeList.txt add_library should be like below,
add_library( # Sets the name of the library.
nativecode
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/nativecode.cpp)
If you notice, i added relative path and i don't know about case Sensitive. please try with smallcase.
I noticed, you mentioned your lib name as "nativeCode" , but in Code you taken only (System.loadLibrary("native")), it should be nativeCode. make sure the name matches for your library.
Add path of your CMakeList.txt in build.gradle (App Level)
android{
...
externalNativeBuild {
cmake {
path "CMakeLists.txt" //consider this CMakeLists.txt inside rootPath/app/CMakeLists.txt
}
}
QUESTION : If I need to specify a path for the app to look for the .so files, where should this be?
If you follow above steps it will work, You no need to specify which is modern and easy way., but if you wish manually i'm sure it bit complex compared to above(atleast for me)
First you have to create .so files from your .cpp file. (for that,we can do with Android.mk and Application.mk)
Then, you can add following line in build.gradle app level.
android{
...
...
sourceSets {
main {
jniLibs.srcDir 'jniLibs' //consider this jniLibs folder under rootPath\app\src\main\jniLibs
}
}
}
Then, you have to add *.so files in rootPath/app/jniLibs/**/*.so.
You have to generate *.so files for all supported ARM like, ("x86", "x86_64", "armeabi", "armeabi-v7a", "arm64-v8a")
then your folder path something like ,
rootPath\app\src\main\jniLibs\arm64-v8a\libnativecode.so,
rootPath\app\src\main\jniLibs\arm64-v7a\libnativecode.so
and so on...
Hope, these clear your issues and your doubts aswell 🤞.
So I am trying to integrate CLE in Android and for this reason I have to add a few .so files. I am following a tutorial from here
Everything works fine till integrating the Star libraries, however when I run the program I get the following exception:
Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: library "/data/data/com.srplab.starcore/lib/libstar_java.so" not found
Now to include these .so files I have created a folder jniLibs and placed .so files for 3 architectures:
I ahve added the following lines of code to my build.gradle:
sourceSets
{
main
{
jniLibs.srcDirs = ['src/main/jnilibs']
}
}
However again when I run the below piece of code:
try {
//System.loadLibrary("mysharedlibrary");
System.load("/data/data/"+getPackageName()+"/libstar_java.so");
} catch (UnsatisfiedLinkError use) {
Log.e("JNI", "WARNING: Could not load libmysharedlibrary.so");
use.printStackTrace();
}
I am getting an exception, means the .so files did not load.
What is the proper way of doing this?
Your "armeabiv7a" folder must be renamed to "armeabi-v7a".
Also there is typo in :
jniLibs.srcDirs = ['src/main/jnilibs']
Your folder is with big L:
jniLibs.srcDirs = ['src/main/jniLibs']
By the way, "src/main/jniLibs" is used by default for native libraries and you do not have to specify it in your gradle scripts.
There is not full block of code above, but do you load your library from static initializer? like:
static
{
System.loadLibrary("star_java");
}
And look at your apk to be sure that your lib were successfully gathered. You can see it at app/build/outputs/apk/
I have imported my android Eclipse project into Android Studio 1.0. The import ignored all of my source code files, so I have manually added them to the project. The error that I am getting is found on all of the activity names found in my AndroidManifest.xml file. For example:
<activity android:name="com.company.myapp.beforelogin.InitialActivity"></activity>
The AndroidManifest is unable to resolve the symbols "beforelogin" and "InitialActivity". I have read here (AndroidStudio : Cannot resolve symbol MainActivity) that Android Studio doesn't recognize my code as source code. So I tried this (How to get Android Studio to recognize file as source (test)) to add my directory as a sourceSet in my build.gradle file, but it didn't work. My project structure looks like this:
-app
-src
-build.gradle
-main
-res
-com
-AndroidManifest.xml
Any help would be greatly appreciated. Thanks.
Assuming that com/ in your structure refers to the root package of your Java source, create a java/ directory as a peer of res/ (i.e., a child of main/) and move com/ into java/.
I have some .cpp and .h files and I created a libs folder and put them there. Then I added in my local.properties
ndk.dir=C\:\\PATH...\\Android\\android-ndk-r10e
and finally I added in my build.gradle the following
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
That's it. I can't run my app and I always get the same error. I've read something about .so files and armeabi folders, but I don't know what is that. Have you solved this problem before? there is something that I am missing?
It's done XD, all that I needed to do is compile the C++ files with the NDK in the terminal using the ndk-build command. It created my .so files in the armeabi folders automatically
I am trying to use the libgdx-freetype libraries that come with LibGDX. For the desktop, I simply added libgdx-freetype.jar and libgdx-natives.jar to the /libs folder of the main project (and added to build path) and it just worked. However, when trying to add the same libraries to /libs folder and the libgdx-freetype.so files to the /libs/armeabi and /libs/armeabi-v7a folders, I get the build error:
Description Resource Path Location Type
Native libraries detected in 'gdx-freetype-natives.jar'. See console for more information.
SlotMachine-android Unknown Android Packaging Problem
In the Eclipse console I have:
[2012-12-05 17:38:04 - SlotMachine-android] The library 'gdx-freetype-natives.jar' contains native libraries that will not run on the device.
[2012-12-05 17:38:04 - SlotMachine-android] The following libraries were found:
[2012-12-05 17:38:04 - SlotMachine-android] - libgdx-freetype.so
[2012-12-05 17:38:04 - SlotMachine-android] - libgdx-freetype64.so
Can someone point out what I am doing wrong?
For Android you do not want gdx-freetype-natives.jar included. That is only for your main project. On Android you just need gdx-freetype.jar and the two .so files in your arm folders. The .so files are the natives for Android.