Ответ 1
Я думаю, вы забыли изменить имя пакета.
Java_com_mindtherobot_samples_ndkfoo
Это должен быть ваш пакет, который вы указали для создания проекта.
Я новичок в разработке ndk в android.I прошел файловую систему ndk android. Здесь, объясняя, что я сделал. 1) я создал папку с именем "jni", затем создаю 2 файла с именем Android.mk и ndkfoo.c.
В 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)
и в ndkfoo.c
#include <string.h>
#include <jni.h>
jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
то я создал класс NdkFooActivity, в котором я написал
// load the library - name matches jni/Android.mk
static {
System.loadLibrary("ndkfoo");
}
Но теперь, когда я строю из cygwin в xp, он создает .so файл успешно, тогда я запускаю приложение для Android. Это дает мне java.lang.UnsatisfiedLinkError в LOGCAT.
Итак, пожалуйста, дайте мне знать, где я ошибаюсь.
Спасибо, Advance,
Я думаю, вы забыли изменить имя пакета.
Java_com_mindtherobot_samples_ndkfoo
Это должен быть ваш пакет, который вы указали для создания проекта.
Также (просто столкнулся с этой проблемой), обратите внимание, что System.loadLibrary() всегда будет генерировать исключение, если вы тестируете эмулятор Intel Atom x86. Он отлично работает на обычных эмуляторах Android и отлаживается на физическом устройстве.
Хотя это не проблема OP, у меня был тот же java.lang.UnsatisfiedLinkError из-за отсутствия
static {
System.loadLibrary("mylibraryname");
}
Там хороший шанс, что подпись неверна, как упомянули другие.
Если вы запустите утилиту javah, вы можете найти точную подпись. Из папки bin в вашем проекте, где находится .apk и корень иерархии классов Java, запустите:
javah -o jni_sig.h com.mindtherobot.whatever.your.package.is.NdkFooActivity
... и если вы правильно назвали имя пакета и имя класса, он будет выписывать заголовок (называемый jni_sig.h) с правильной сигнатурой функции для любых нативных функций. Скопируйте это в свой заголовок и .c файл, добавив параметры по мере необходимости, и он должен работать правильно.
Возможно, это уже не актуально, но насколько я знаю, вам также нужно добавить префикс "lib" к имени вашей родной библиотеки. В вашем случае вам нужно изменить Android.mk на "LOCAL_MODULE: = libndkfoo" и сохраните "System.loadLibrary(" ndkfoo "); как есть. Проверьте код образца ndk.
Я уверен, что это должно быть:
JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
Какой SDK вы нацеливаете и какая версия NDK у вас есть? Получается ли ошибка, которую вы получаете, говорит, что она не может загрузить библиотеку вообще или что существует нереализованный метод? В любом случае убедитесь, что у вас нет андроида: hasCode = "false", установленный в теге приложения в манифесте.
Вы также можете открыть файл APK после сборки с помощью winrar или что-то подобное, чтобы убедиться, что файл libndkfoo.so действительно включен в пакет.
В любом случае, если вы не объявляете собственную функцию в NdkFooActivity, вы получите эту ошибку, т.е.
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!");
}
проблема заключается в том, что вы компилируете для целевого процессора и выполняете в другом. если вы компилируете в ARM (armeabi), то выполняйте в эмуляторе на основе armeabi. создайте файл под названием application.mk в той же папке, что и Android.mk, и поместите внутри него один из следующих:
затем выполните компиляцию- > выполнить. он должен работать.
Создайте файл Application.mk в jni-папке. Скопируйте следующую строку и вставьте ее в Application.mk и сохраните. Теперь создайте проект с помощью cgywin и снова запустите.
APP_ABI: = armeabi armeabi-v7a
Имя метода Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction
может быть не таким же, как имя вашего пакета или имя класса.
Чтобы сделать это наименование метода точно таким же, вы должны использовать javah
.
Это сделает заголовочный файл, который будет иметь то же самое имя метода, которое требуется. Чтобы этот заголовочный файл перейти в папку классов в корзине вашего проекта (убедитесь, что вы создали java файл со статическим методом и постройте его правильно) с помощью этой команды в терминале
~/workspace/Android_Example2/bin/classes$
В этом каталоге введите следующую команду
sudo javah -jni com.NDK.android_example2.MainActivity
Измените имя пакета и имя класса в соответствии с вашим проектом. Это создаст com_NDK_android_example2_MainActivity.h в вашей папке классов.
Просто переместите этот файл в папку jni
. В этом файле будут созданы статические методы, которые вы создали в файле MainActivity.java, но они просто объявлены не реализованы, которые будут реализованы в вашем файле C
.
ПРИМЕЧАНИЕ. При копировании метода проверьте, должны ли быть объявлены параметры метода, поэтому объявите их в файле C
.
Надеюсь на эту помощь.
У меня также была ошибка java.lang.UnsatisfiedLinkError
. Я подтвердил все упоминания в ответах выше, но все еще получал ошибку. В конце концов я обнаружил, что имена методов JNI не могут иметь подчеркивания.
Пример:
Java_com_example_app_NativeLib_print_out_stuff
< - генерирует java.lang.UnsatisfiedLinkError: print_out_stuff
Переименуйте функцию print_out_stuff на что-то без подчеркивания:
Java_com_example_app_NativeLib_printOutStuff
< - works
здесь учебник, как использовать собственный код: здесь
убедитесь, что у вас нет пробелов в пути к проекту. также вы не можете использовать подчеркивание в своем пакете или имени проекта.
Замените это
Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction
С
Java_your_packege_name_your_Activity_Name_invokeNativeFunction
Пример, если ваш пакет является com.pack, а имя Activity Name - MainActivity, затем
Java_com_pack1_MainActivity_invokeNativeFunction
Не забудьте добавить ссылку в действие.
//загружать библиотеку - имя соответствует jni/Android.mk
static {
System.loadLibrary("ndkfoo");
}
public native String invokeNativeFunction();
Повторите все эти шаги, чтобы они работали:)