System.loadLibrary (…) no podría encontrar biblioteca nativa en mi caso

Quiero usar una biblioteca nativa existente de otro proyecto de Android, así que acabo de copiar la librería NDK ( libcalculate.so ) a mi nuevo proyecto de Android. En mi nuevo proyecto de Android creé una libs/armeabi/ carpeta y puse libcalculate.so allí. No hay jni / carpeta. Mi dispositivo de prueba tiene arquitectura ARM.

En mi código java cargar la biblioteca por:

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

Cuando ejecuto mi nuevo proyecto de Android, tengo error:

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

Por lo tanto, como dice el error, la biblioteca nativa copiada no está en / verdor / lib o / system / lib, ¿cómo resolver este problema en mi caso?

(Yo unziped el paquete apk, en lib / hay libcalculate.so)

==== UPDATE =====

También intenté crear una carpeta jni / bajo la raíz del proyecto, y añadir un archivo de Android.mk bajo jni /. El contenido de Android.mk es:

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

Luego, bajo la raíz del proyecto, ejecuté ndk-build. Después de eso, los armeabi / y armeabi-v7a / directorios son generados por ndk-build (con libcalculate.so dentro de la carpeta).

A continuación, ejecutar mi maven construir el proyecto con éxito. En el paquete final de apk, hay:

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

Pero cuando ejecuto mi aplicación, el error mismo error:

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

8 Solutions collect form web for “System.loadLibrary (…) no podría encontrar biblioteca nativa en mi caso”

A raíz de la causa (y tal vez resolver su problema en el mismo tiempo), aquí es lo que puede hacer:

  1. Quite la carpeta jni y todos los archivos .mk . Usted no necesita estos ni el NDK si no está compilando nada.

  2. Copie su archivo libcalculate.so dentro de <project>/libs/(armeabi|armeabi-v7a|x86|...) . Cuando utilizas Android Studio, es <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...) , pero veo que estás usando eclipse.

  3. Construya su APK y ábralo como un archivo zip , para comprobar que su archivo libcalculate.so está dentro de lib / (armeabi | armeabi-v7a | x86 | …) .

  4. Quite e instale su aplicación

  5. Ejecutar paquetes de paquetes dumpsys | Grep yourpackagename para obtener el nativeLibraryPath o legacyNativeLibraryDir de su aplicación.

  6. Ejecute ls en el nativeLibraryPath que tenía o en legacyNativeLibraryDir / armeabi , para comprobar si su libcalculate.so está realmente allí.

  7. Si está allí, compruebe si no se ha alterado de su archivo original de libcalculate.so : es compilado contra la arquitectura derecha, contiene los símbolos esperados, hay cualquier dependencia que falta. Usted puede analizar libcalculate.so usando readelf.

Para comprobar el paso 5-7, puede usar mi aplicación en lugar de líneas de comando y readelf: Native Libs Monitor

PS: Es fácil confundirse con los ficheros .so que se deben poner o generar de forma predeterminada, aquí hay un resumen:

  • Libs / CPU_ABI dentro de un proyecto eclipse

  • JniLibs / CPU_ABI dentro de un proyecto de Android Studio

  • Jni / CPU_ABI dentro de un AAR

  • Lib / CPU_ABI dentro del APK final

  • Dentro del nativeLibraryPath de la aplicación en un dispositivo <5.0, y dentro del legacyNativeLibraryDir / CPU_ARCH de la aplicación en un dispositivo> = 5.0.

Donde CPU_ABI es cualquiera de: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64 . Dependiendo de las arquitecturas a las que apunte y de las librerías que se han compilado.

Tenga en cuenta también que los libs no se mezclan entre los directorios CPU_ABI: se necesita el conjunto completo de lo que se está utilizando, un lib que está dentro de la carpeta armeabi no se instalará en un dispositivo armeabi-v7a si hay libs dentro del armeabi -v7a del APK.

En gradle, después de copiar todas las carpetas de archivos a libs/

 jniLibs.srcDirs = ['libs'] 

La adición de la línea anterior a los sourceSets de sourceSets en el archivo build.gradle funcionó. Nada más funcionaba en absoluto.

¿Utiliza gradle? Si es así, coloque el archivo .so en <project>/src/main/jniLibs/armeabi/

Espero que ayude.

En mi caso, debo excluir la compilación de fuentes por gradle y establecer libs path

 android { ... sourceSets { ... main.jni.srcDirs = [] main.jniLibs.srcDirs = ['libs'] } .... 

Trate de llamar a su biblioteca después de incluir la sección PREBUILT_SHARED_LIBRARY :

 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 

Actualizar:

Si va a utilizar esta biblioteca en Java necesita compilarlo como biblioteca compartida

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

Y necesita implementar la biblioteca en el directorio /vendor/lib .

Como referencia, tuve este mensaje de error y la solución fue que cuando especificas la biblioteca pierdes el 'lib' en el frente y el '.so' desde el final.

Por lo tanto, si tiene un archivo libmyfablib.so, debe llamar a:

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

Después de haber mirado en el apk, instalado / desinstalado y probado todo tipo de soluciones complejas no pude ver el problema simple que estaba justo en frente de mi cara!

En mi experiencia, en un móvil armeabi-v7a, cuando los directorios armeabi y armeabi-v7a están presentes en el apk, los archivos .so en el directorio armeabi no estarán enlazados, aunque los archivos .so en armeabi SERAN enlazados en el Mismo armeabi-v7a móvil, si armeabi-v7a no está presente.

En realidad, no puedes simplemente poner un archivo .so en /libs/armeabi/ y cargarlo con System.loadLibrary . Debe crear un archivo Android.mk y declarar un módulo precompuesto en el que especifique su archivo .so como fuente.

Para ello, coloque su archivo .so y el archivo Android.mk en la carpeta jni . Tu Android.mk debería verse así:

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

Fuente: Android NDK documentación sobre pre-construido

  • ¿Cómo puedo capturar SIGSEGV (error de segmentación) y obtener un seguimiento de pila bajo JNI en Android?
  • Oficial "Boost library" ¿Soporte para Android e iOS?
  • ¿Alguna manera de usar una base de datos incrustada Firebird en una aplicación Android nativa (NDK)?
  • Cómo detectar la compilación de android ndk en un archivo C / C ++?
  • ¿Qué sustituye a GraphicBuffer en Android 7.0?
  • Mensaje de advertencia de Google Play y OpenSSL
  • Creación de una función personalizada en sqlite3 en android
  • ¿Cómo orientar múltiples arquitecturas mediante NDK?
  • Llame a métodos de clase C ++ o funcione desde Java en android sin recrear clase / variable en cada llamada
  • No se carga ninguna tabla de símbolos. Utilice el comando "file". Con eclipse y NDK
  • Comando ndk-build no se encuentra en el terminal de Ubuntu
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.