¿Cómo resolver el java.lang.UnsatisfiedLinkError en NDK en Android?

Soy nuevo en el desarrollo de ndk en Android. He pasado por el sistema de archivos de ndk android. Aquí, explicando lo que hice. 1) he creado una carpeta llamada “jni” y luego creo 2 archivos llamados Android.mk y ndkfoo.c.

En Android.mk

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Here we give our module name and source file(s) LOCAL_MODULE := ndkfoo LOCAL_SRC_FILES := ndkfoo.c include $(BUILD_SHARED_LIBRARY) 

y en ndkfoo.c

 #include  #include  jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) { return (*env)->NewStringUTF(env, "Hello from native code!"); } 

luego creé la clase NdkFooActivity, en la que escribí

 // load the library - name matches jni/Android.mk static { System.loadLibrary("ndkfoo"); } 

Pero ahora, cuando construyo desde cygwin en xp, creo el archivo .so con éxito, luego ejecuto la aplicación de Android. Me da java.lang.UnsatisfiedLinkError en LOGCAT.

Por lo tanto, hágamelo saber dónde estoy equivocado.

Gracias por adelantado,

Creo que olvidó cambiar el nombre del paquete.

Java_com_mindtherobot_samples_ndkfoo

Debe ser su paquete lo que ha especificado creando el proyecto.

Además (acabo de enterarme de este problema), tenga en cuenta que System.loadLibrary () arrojará siempre una excepción si está probando el emulador Intel Atom x86. Funciona muy bien en los emuladores regulares de Android y la depuración en un dispositivo físico.

Aunque este no ha sido el problema del OP, tuve el mismo java.lang.UnsatisfiedLinkError porque faltaba

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

Existe una buena posibilidad de que la firma sea incorrecta, como han mencionado otros.

Si ejecuta la utilidad javah, puede encontrar la firma exacta. Desde la carpeta bin de su proyecto, donde está el archivo .apk y se genera la raíz de la jerarquía de la clase Java, ejecute:

javah -o jni_sig.h com.mindtherobot.whatever.your.package.is.NdkFooActivity

… y, si obtuvo el nombre del paquete y el nombre de clase correctos, escribirá un encabezado (llamado jni_sig.h) con la (s) firma (s) de función correcta (s) para cualquier función nativa. Copie eso en su encabezado y archivo .c, agregue parámetros según sea necesario, y debería funcionar correctamente.

Quizás ya no sea relevante pero, por lo que yo sé, también necesitas agregar el prefijo “lib” al nombre de tu biblioteca nativa. En su caso, debe cambiar el Android.mk a “LOCAL_MODULE: = libndkfoo” y mantener “System.loadLibrary (” ndkfoo “);” como están las cosas. Verifique el código de muestra ndk.

Estoy bastante seguro de que debería ser:

 JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) { return (*env)->NewStringUTF(env, "Hello from native code!"); } 

¿A qué SDK está apuntando y qué versión del NDK tiene usted? ¿El error que recibes dice que no pudo cargar la biblioteca o que hubo un método no implementado? De cualquier manera, asegúrese de que no tenga android: hasCode = “false” establecido en la etiqueta de la aplicación en su manifiesto.

También puede abrir el archivo APK después de una comstackción utilizando winrar o algo similar para asegurarse de que el archivo libndkfoo.so realmente se está incluyendo con el paquete.

De cualquier manera, si no declaras la función nativa en NdkFooActivity obtendrás ese error, es decir,

public static native String invokeNativeFunction ();

 JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) { return (*env)->NewStringUTF(env, "Hello from native code!"); } 

el problema es que comstacks para un procesador de destino y lo ejecutas en otro. si comstack en ARM (armeabi), entonces ejecute emulador basado en armeabi. crea un archivo llamado application.mk en la misma carpeta que Android.mk y pon en él uno de estos:

  1. APP_ABI: = x86
  2. APP_ABI: = armeabi
  3. APP_ABI: = mips
  4. APP_ABI: = armeabi x86 mips // para comstackr en todos los destinos y obtendrás 3 * .so archivos

luego comstackr-> ejecutar. deberia de funcionar.

Cree un archivo Application.mk en la carpeta jni. Copie la siguiente línea y péguelo en Application.mk y guarde. Ahora cree el proyecto con su cgywin y vuelva a ejecutarlo

APP_ABI: = armeabi armeabi-v7a

El nombre del método Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction

puede no ser el mismo que el nombre del paquete o el nombre de clase. Para que este nombre de método sea exactamente el mismo, debe usar javah .

Esto hará que un archivo de encabezado tenga el mismo nombre de método requerido. Para hacer que este archivo de encabezado vaya a la carpeta de clases en el contenedor de su proyecto (asegúrese de haber creado el archivo java con el método estático y comstackrlo correctamente) ) por este comando en tu terminal

~/workspace/Android_Example2/bin/classes$

En este directorio escriba el siguiente comando

 sudo javah -jni com.NDK.android_example2.MainActivity 

Cambie el nombre del paquete y el nombre de la clase de acuerdo con su proyecto. Esto creará una com_NDK_android_example2_MainActivity.h en su carpeta de clases.

Simplemente mueva este archivo a su carpeta jni . En este archivo, habrá métodos estáticos que haya creado en el archivo MainActivity.java, pero se han declarado no implementados y se implementarán en su archivo C

NOTA: Al copiar el método, compruebe que los parámetros del método deben declararse, por lo que debe declararlos en su archivo C

Espero que esto ayude.

También tuve un error java.lang.UnsatisfiedLinkError . Verifiqué todo lo mencionado en las respuestas anteriores, pero aún recibía el error. Finalmente descubrí que los nombres del método JNI no pueden tener guiones bajos.

Ejemplo: Java_com_example_app_NativeLib_print_out_stuff < - genera java.lang.UnsatisfiedLinkError: print_out_stuff

Cambia el nombre de la función print_out_stuff a algo sin guiones bajos: Java_com_example_app_NativeLib_printOutStuff < - works

Aquí hay un tutorial sobre cómo usar el código nativo: aquí

asegúrese de no tener ningún espacio en la ruta de su proyecto. tampoco puede usar un guión bajo en el nombre de su paquete o proyecto.

Reemplace esto

 Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction 

Con

 Java_your_packege_name_your_Activity_Name_invokeNativeFunction 

Ejemplo si su paquete es com.pack y el nombre del nombre de la actividad es MainActivity luego

 Java_com_pack1_MainActivity_invokeNativeFunction 

No olvides agregar referencia en la Actividad.

// cargar la biblioteca – el nombre coincide con jni / Android.mk

 static { System.loadLibrary("ndkfoo"); } public native String invokeNativeFunction(); 

Repita todos estos pasos debería funcionar 🙂