返回 登录
0

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

该错误类型较多,以下进行分类:
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//lib目录下
当准备加载native层的so时,虽然在APK中有对应的so文件,但是由于手机设备没有足够的空间加载该so,导致加载失败,产生上述崩溃。

3.So加载库的选择错误
倘若So正确生成,且手机空间充足,那么如上所述,在Android系统中,当我们安装apk文件的时候,lib目录下的so文件会被解压到app的原生库目录,一般来说是放到/data/data//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

评论