android通过Jni加载so库遇到UnsatisfiedLinkError问题!!!
错误信息:
java.lang.UnsatisfiedLinkError: hsl.p2pipcam.nativecaller.NativeCaller
at hsl.p2pipcam.manager.DeviceSDK.createDevice(DeviceSDK.java:74)
at hsl.p2pipcam.manager.Device.createDevice(Device.java:66)
at cn.yycloud.fragments.WebCameraFragment.onClick(WebCameraFragment.java:256)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
终于解决了困扰我半个世纪的难题,记录下:
我的项目中使用了别人的so类,已经打包好了,且只有armeabi这一种。按说应该是兼容性最好的了,但是问题偏偏出现了!!!
一旦加载so时就会报错Java.lang.UnsatisfiedLinkError ,各种千百度和google只有和我类似,从没有和我一样的情况。从出现这个问题 到现在解决 中间省略可以绕地球一圈的文字。。。
so库交叉编译时 可选arm,x86,mips三种架构,者三种结构还有32位于64位之分。
百度得知其中有个坑:
如果你的项目中有arm64-v8a,当你的app在64位arm架构的cpu手机上运行时,只会从arm64-v8a找so库,找不到就报错,不会再去armeabi-v7a和armeabi里去再找。
如果没有arm64-v8a文件夹的话,会从armeabi-v7a找,找不到就去armeabi找。都找不到才报错。
但是!!!经过N次报错后,,,
我发现手机只会根据cpu找对应文件夹下的so加载,没有就特么的直接报错,根本不会重新去别的文件夹下找!!!!(我怀疑可能eclipse和Android studio编译的原因,或者新版安卓系统加载so库的策略改变了)
最后我的解决办法是:新建armeabi,armeabi-v7a,arm64-v8a,arm-v8a,然后在四个文件夹内 分别拷贝一份so库放入。