如何在Android中解决NDK中的java.lang.UnsatisfiedLinkError?
我是在android.nd中开发的ndk新手,我经历了ndk android的文件系统。 在这里,解释我做了什么。 1)我创建了一个名为“jni”的文件夹,然后创建2个名为Android.mk和ndkfoo.c的文件。如何在Android中解决NDK中的java.lang.UnsatisfiedLinkError?
在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");
}
但现在当我从XP中的cygwin构建它创建.so文件成功,然后我作为Android应用程序运行。它在LOGCAT中给了我java.lang.UnsatisfiedLinkError。
所以,请让我知道我错了。
在此先感谢,
像其他人提到的那样,签名是错误的。
如果您运行javah实用程序,则可以找到确切的签名。从项目中的bin文件夹中.apk所在的位置和Java类层次结构的根目录生成,运行:
javah -o jni_sig.h com.mindtherobot.whatever.your.package.is.NdkFooActivity
...并且,如果您的软件包名称和类名正确,它将为所有本机函数写出一个包含正确函数签名的头文件(称为jni_sig.h)。将其复制到头文件和.c文件中,根据需要添加参数,并且它应该可以正常工作。
谢谢。在我的系统上,它需要从Classes子目录运行。 – weston 2012-09-04 17:39:38
我想你忘了更改包名。
Java_com_mindtherobot_samples_ndkfoo
它应该是你的包你所指定的创建项目。
我敢肯定这应该是:
JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
哪个SDK你定位和你有其中的NDK版本?您收到的错误是否说明它无法加载该库或者存在未实现的方法?无论哪种方式确保您的清单中的应用程序标记上没有设置android:hasCode =“false”。
你也可以使用winrar或类似的东西打开APK文件,确保libndkfoo.so文件实际上被包含在软件包中。
无论哪种方式,如果你不声明本机功能NdkFooActivity你会得到错误,即
公共静态本地字符串invokeNativeFunction();
虽然这不是OP的问题,但我有相同的java.lang。UnsatisfiedLinkError由于缺少
static {
System.loadLibrary("mylibraryname");
}
通常它会导致以下问题:'java.lang.ExceptionInInitializerError java.lang.UnsatisfiedLinkError:Library xyz ... not found' – ademar111190 2012-11-13 18:09:40
如何在上述情况下解决它? – Ahmed 2013-02-21 21:30:40
创建JNI folder.Copy文件Application.mk以下行并将其粘贴到Application.mk和save.Now建立与您cgywin项目,然后再次运行
APP_ABI的: = armeabi armeabi-v7a
也许不相关了,但据我所知,你还需要添加“lib”前缀到你的本地库名称。在你的情况下,你需要将Android.mk更改为 “LOCAL_MODULE:= libndkfoo”并保留“System.loadLibrary(”ndkfoo“);”就这样。检查ndk示例代码。
它不能解决仍然存在的问题...... – 2013-10-07 18:32:03
另外(只是遇到了这个问题),请注意,如果您在Intel Atom x86仿真器上测试,System.loadLibrary()将始终引发异常。它适用于普通的Android仿真器,并在物理设备上进行调试。
+1帮助。你怎么知道这件事的? – quinestor 2013-07-11 13:04:21
@Daniel Rodriguez:谢谢soooooooooo。 :) :) :) – 2013-07-13 09:36:32
+1,是的,你是怎么知道的? – 2013-11-08 16:21:25
我也有一个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
< - 工程
方法名Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction
可能是不一样的,你的包名或类名。 要使方法的命名完全相同,您必须使用javah
。
这将创建一个头文件,它将具有所需的相同方法名称。要将此头文件转到项目bin的classes文件夹中(确保已使用静态方法创建了java文件而在终端
~/workspace/Android_Example2/bin/classes$
构建得当)该命令在该目录中根据写下面的命令
sudo javah -jni com.NDK.android_example2.MainActivity
更改包名和类名的project.This将在您的classes文件夹中创建一个com_NDK_android_example2_MainActivity.h。
只需将此文件移动到您的jni
文件夹。在这个文件中,将会有在MainActivity.java文件中创建的静态方法,但是它们只是声明没有实现,您将在您的C
文件中实现。
注意:虽然应对方法检查方法参数是需要声明的,所以让他们声明在您的C
文件中。
希望得到这个帮助。
,如果你的包是com.pack和活动名称的名字是MainActivity然后
Java_com_pack1_MainActivity_invokeNativeFunction
不要忘记添加引用替换此
Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction
随着
Java_your_packege_name_your_Activity_Name_invokeNativeFunction
例在活动中。
//加载库 - 名称相匹配的JNI/Android.mk
static {
System.loadLibrary("ndkfoo");
}
public 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的模拟器中执行。 创建在同一文件夹中Android.mk称为application.mk,把里面的这一个文件:
- APP_ABI:= 86
- APP_ABI:= armeabi
- APP_ABI:= MIPS
- APP_ABI:= armeabi x86 mips //在所有目标中进行编译,您将获得3 * .so文件
然后编译 - >运行。 它应该工作。
在真实设备中执行,并且工作正常。谢谢.... – 2016-09-26 06:13:51
您确定您声明invokeNativeFunction()的类实际上是com.mindtherobot.samples.ndkfoo.NdkFooActivity?您可以发布所有代码 – ognian 2010-07-17 19:14:11
具体而言,请在.java文件中包含本地方法的声明。也显示“包”和“类”声明。另外,将JNI_OnLoad函数添加到共享库中,并在其中放入一些日志记录,以便确保该库成功加载。 – fadden 2010-07-19 17:47:53
在ndkfoo.c中检查此声明Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction,这应该更改为您的软件包名称,如Java_com_your_package_ndkfoo_NdkFooActivity_invokeNativeFunction – pradeep 2011-04-30 11:31:49