System.loadLibrary (...) could not find the native library in my case

I want to use my existing native library from another Android project, so I just copied the NDK library ( libcalculate.so ) into my new Android project. In my new Android project, I created the libs/armeabi/ folder and placed libcalculate.so there. There is no jni / folder. My test device has an ARM architecture.

In my java code, I load the library:

  static{ System.loadLibrary("calculate"); } 

When I launch my new Android project, I got an error:

 java.lang.UnsatisfiedLinkError: ... nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so" 

So, as the error says, the copied native library is not in / verdor / lib or / system / lib, how to solve this problem in my case?

(I unpacked the apk package, in lib / there is libcalculate.so)

==== ===== UPDATE

I also tried to create a jni / folder under the project root and add the Android.mk file to jni /. Android.mk content:

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libcalculate LOCAL_SRC_FILES := libcalculate.so include $(PREBUILT_SHARED_LIBRARY) 

Then, at the root of the project, I executed ndk-build. After that, the armeabi / and armeabi-v7a / directories are generated by ndk-build (with libcalculate.so inside the folder).

Then I launched the maven project to create the project. The latest apk package has:

 lib/armeabi/libcalculate.so lib/armeabi-v7a/libcalculate.so 

But when I run my application, the same error code:

 java.lang.UnsatisfiedLinkError: ... nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so" 
+48
android android-ndk
Dec 11 '14 at 10:54
source share
10 answers

To invoke the cause (and possibly solve your problem at the same time), here is what you can do:

  • Delete the jni folder and all .mk files. You do not need these or NDKs if you are not compiling anything.

  • Copy the libcalculate.so file inside <project>/libs/(armeabi|armeabi-v7a|x86|...) . When using Android Studio, it is <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...) , but I see that you are using eclipse.

  • Create an APK and open it as a zip file to verify that your libcalculate.so file is inside lib / (armeabi | armeabi-v7a | x86 | ...) .

  • Uninstall and install the application

  • Running dumpsys package packages | grep yourpackagename to get your application's nativeLibraryPath or legacyNativeLibraryDir.

  • Run ls on nativeLibraryPath that you had or on legacyNativeLibraryDir / armeabi to check if your libcalculate.so is valid.

  • If it is there, check to see if it has changed from the libcalculate.so source file: it compiled against the correct architecture, does it contain the expected characters, are there any flaws. You can analyze libcalculate.so using readelf.

To check step 5-7, you can use my application instead of the command line and readelf: Native Libs Monitor

PS: It's easy to confuse where .so files should be placed or generated by default, here is a summary:

  • libs / CPU_ABI inside an eclipse project

  • jniLibs / CPU_ABI in an Android Studio project

  • jni / CPU_ABI inside AAR

  • lib / cpu_abi inside final apk

  • inside the nativeLibraryPath application on the device <5.0 and inside the legacyNativeLibraryDir / CPU_ARCH application on the device> = 5.0.

Where CPU_ABI is any of: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64. Depending on which architectures you are targeting and your libraries have been compiled.

Please also note that libs do not mix between the CPU_ABI directories: you need a full set of what you use, the lib located inside the armeabi folder will not be installed on the armeabi-v7a device if there are any libs inside the armeabi- folder v7a from the APK.

+111
Dec 17 '14 at 10:26
source share

In gradle, after copying all the file folders to libs/

 jniLibs.srcDirs = ['libs'] 

Adding the above line to sourceSets in the build.gradle file. Nothing else worked.

+10
Mar 24 '15 at 15:49
source share

Do you use gradle? If so, put the .so file in <project>/src/main/jniLibs/armeabi/

Hope this helps.

+8
Dec 15 '14 at 15:32
source share

In my case, I have to exclude compiling sources with gradle and set the libs path

 android { ... sourceSets { ... main.jni.srcDirs = [] main.jniLibs.srcDirs = ['libs'] } .... 
+5
Oct 27 '15 at 13:06 on
source share

Try calling your library after the PREBUILT_SHARED_LIBRARY section:

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libcalculate LOCAL_SRC_FILES := <PATH>/libcalculate.so include $(PREBUILT_SHARED_LIBRARY) #... LOCAL_SHARED_LIBRARIES += libcalculate 

Update:

If you will use this library in Java, you need to compile it as a shared library

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libcalculate LOCAL_SRC_FILES := <PATH>/libcalculate.so include $(BUILD_SHARED_LIBRARY) 

And you need to deploy the library in the /vendor/lib directory.

+3
Dec 15 '14 at 10:46
source share

For reference, I got this error message, and the solution was that when you specify the library, you skip "lib" in front and ".so" from the end.

So, if you have the libmyfablib.so file, you need to call:

  System.loadLibrary("myfablib"); // this loads the file 'libmyfablib.so' 

After looking in the apk, installed / uninstalled and tried all kinds of complex solutions, I could not see the simple problem that was right in front of my face!

+1
Jul 20 '17 at 11:10
source share

add all suport

application / build.gradle

 ndk { moduleName "serial_port" ldLibs "log", "z", "m" abiFilters "arm64-v8a","armeabi", "armeabi-v7a", "x86","x86_64","mips","mips64" } 

Application \ SRC \ JNI \ Application.mk

 APP_ABI := arm64-v8a armeabi armeabi-v7a x86 x86_64 mips mips64 
0
Sep 14 '17 at 8:29
source share

This is an update for Android 8.

In an earlier version of Android, for my own LoadLibrary libraries (for access via JNI, for example), I connected my own code to iterate through a number of potential paths to the lib folder, based on various apk settings / update algorithms:

 /data/data/<PackageName>/lib /data/app-lib/<PackageName>-1/lib /data/app-lib/<PackageName>-2/lib /data/app/<PackageName>-1/lib /data/app/<PackageName>-2/lib 

This approach is hokey and will not work for Android 8; from https://developer.android.com/about/versions/oreo/android-8.0-changes.html you will see that as part of their "Security" changes you now need to use sourceDir:

"You can no longer assume that APKs are in directories whose names end in -1 or 2. Applications should use sourceDir to get the directory and not rely directly on the directory format.

The fix, sourceDir is not a way to find your native shared libraries; use something like. Tested for Android 4.4.4 → 8.0

 // Return Full path to the directory where native JNI libraries are stored. private static String getNativeLibraryDir(Context context) { ApplicationInfo appInfo = context.getApplicationInfo(); return appInfo.nativeLibraryDir; } 
0
Nov 17 '17 at 13:09 on
source share

In my experience, on an armeabi-v7a mobile device, when both armeabi and armeabi-v7a are present on the apk, the .so files in the armeabi directory will not be linked, although the .so files in armeabi will be linked in the same mobile as armeabi -v7a if armeabi-v7a is not.

-one
Aug 17 '15 at 4:01
source share

in fact, you cannot just put the .so file in /libs/armeabi/ and load it using System.loadLibrary . You need to create an Android.mk file and declare a pre-built module in which you specify your .so file as the source.

To do this, put your .so file and the Android.mk file in the jni folder. Your Android.mk should look something like this:

 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libcalculate LOCAL_SRC_FILES := libcalculate.so include $(PREBUILT_SHARED_LIBRARY) 

Source: Android NDK Ready-made documentation

-2
Dec 15 '14 at 10:23
source share



All Articles