10月30, 2015

java.lang.UnsatisfiedLinkError,findLibrary returned null的一种可能的解决方式

今天弄NDK+JNI,编译没问题,但死活运行失败,报的错误是:

 E/AndroidRuntime(10679): java.lang.UnsatisfiedLinkError: Couldn't load libfilterengine from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.qihoo.abptest-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.qihoo.abptest-2, /vendor/lib, /system/lib]]]: findLibrary returned null

中间纠结的过程就不说了,直接说结果:

我出错的时候是这么写的:

public class JniTest{
static{
System.loadLibrary("libfilterengine.so");
}
public long runJs(String js){
stringFromJNI();
return 1;
}
public native void  stringFromJNI();
}

后来改成这样写就可以了:

public class JniTest{
static{
System.loadLibrary("filterengine");
}
public long runJs(String js){
stringFromJNI();
return 1;
}
public native void  stringFromJNI();
}

看出区别了吗?

就是loadLibrary()函数中,传入的名字必须是没有“lib”前缀和“.so”后缀的,否则就会引发上面的错误。

看看文档中的描述:

Open Declarationvoid java.lang.Runtime.loadLibrary(String nickname)
Loads a shared library. Class loaders have some influence over this process, but for a typical Android app, it works as follows:

Given the name "MyLibrary", that string will be passed to System.mapLibraryName. That means it would be a mistake for the caller to include the usual "lib" prefix and ".so" suffix.

That file will then be searched for on the application's native library search path. This consists of the application's own native library directory followed by the system's native library directories.

然而调用System.load()的时候是可以写全名的,我一开始都用的是load,结果踩坑了,一直以为是cpp交叉编译的问题。。。

本文链接:http://www.siki.space/post/a_possible_way_to_solve_unstatisfiedlinkerror.html

-- EOF --

Comments