您的位置:首页 > 移动开发 > Android开发

Android Crash解决方案之java.lang.UnsatisfiedLinkError

2016-07-13 10:55 585 查看
该错误类型较多,以下进行分类:
1、java.lang.UnsatisfiedLinkError : dlopen failed: library //dlopen打开失败

2、java.lang.UnsatisfiedLinkError :findLibrary returned null //找不到library

3、java.lang.UnsatisfiedLinkError : Native method not found //找不到对应函数

4、java.lang.UnsatisfiedLinkError :Cannot load library: load_library //无法load library

出现原因:

显然出现上述崩溃的根本原因是

1)So无法加载,可能是So不存在等原因

2)So正常加载,但是没有找到相应的函数

针对第二个原因,显然相对来说很容易排查,而且在开发中,这样的函数调用必然会在编译时和debug模式下进行测试,所以这种原因产生的概率很小。

那么下面主要总结几类“So无法加载”而导致上述崩溃的几种原因:

1.生成的So本身缺陷
一个简单的例子:
crash堆栈:
120 20008-20008/com.netease.nis.apptestunit E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: Cannot load library: find_library(linker.cpp:889): "/data/data/com.netease.nis.apptestunit/app_lib/libdemo.so" failed to load previously
 at java.lang.Runtime.load(Runtime.java:340)
 at java.lang.System.load(System.java:521)
 at com.netease.nis.bugrpt.ReLinker.loadLibrary(ReLinker.java:76)
 at com.example.crash.MainActivity.onCreate(MainActivity.java:272)
 at android.app.Activity.performCreate(Activity.java:5220)
 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1086)
 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2193)
 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2279)
 at android.app.ActivityThread.access$600(ActivityThread.java:142)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1272)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:137)
 at android.app.ActivityThread.main(ActivityThread.java:5105)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:511)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
 at dalvik.system.NativeStart.main(Native Method)


解决方法:

查看原项目Application.mk

发现

APP_STL :=  gnustl_shared 



APP_STL 可用值

system  系统默认

stlport_static - 使用STLport作为静态库

stlport_shared - 使用STLport 作为共享库

gnustl_static  -  使用GNU libstdc++ 作为静态库

gnustl_shared -  使用GNU libstdc++ 作为共享库

原方案使用的是共享库,这不一定都支持所有的机型,改用静态库gnustl_static  问题解决。

对应的在Android Studio中:需要将共享库改用静态库gnustl_static  

这一类关于so编译共享库问题,需要进行检查。

上述例子只是一个简单的例子,可能在So编译生成时,由于没有考虑共享库的机型匹配等原因导致UnsatisfiedLinkError崩溃,其次是64位32位系统架构问题,也可能导致UnsatisfiedLinkError崩溃。

2.手机设备没有空间

在So正确生成情况下,会根据设置的支持So库框架生成对应的库。

在Android系统中,当我们安装apk文件的时候,lib目录下的so文件会被解压到app的原生库目录,一般来说是放到/data/data/<package-name>/lib目录下

当准备加载native层的so时,虽然在APK中有对应的so文件,但是由于手机设备没有足够的空间加载该so,导致加载失败,产生上述崩溃。

3.So加载库的选择错误

倘若So正确生成,且手机空间充足,那么如上所述,在Android系统中,当我们安装apk文件的时候,lib目录下的so文件会被解压到app的原生库目录,一般来说是放到/data/data/<package-name>/lib目录下。但是根据系统和CPU架构的不同,其拷贝策略也是不一样的。倘若不正确地配置了so文件,比如某些app使用第三方的so时,只配置了其中某一种CPU架构的so,可能会造成app在某些机型上的适配问题,产生上述崩溃。

具体解决方案请参考链接:

技术分享 / Android
系统安装 apk 时解压 so 的逻辑问题 :http://crash.163.com/index.do#news/!newsId=5

技术分享/Android 加载 SO 库 UnsatisfiedLinkError 错误的原因及解决方案:http://crash.163.com/index.do#news/!newsId=4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息