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 cargar mi propia clase Java en C en Android?
  • ¿Cómo comprobar el dispositivo que ejecuta el nivel API utilizando c código a través de NDK?
  • NDK: ¿GetByteArrayElements copia datos de Java a C ++?
  • Ndk-gdb: "Ninguna tabla de símbolos está cargada"
  • No es capaz de golpear el punto de interrupción en ndk-gdb en Android
  • ¿Es posible reiniciar el teléfono con Android SDK o NDK?
  • No se puede cargar la biblioteca: reloc_library : no se puede localizar 'rand'
  • Cómo transmitir a ffserver desde android
  • ¿Utilizar el teléfono Android como ARM dev board?
  • Cómo enviar MAC marco de datos de difusión con Android AP
  • Creación / búsqueda de bibliotecas compartidas desde el código fuente de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.