java.lang.UnsatisfiedLinkError

    java.lang.UnsatisfiedLinkError: Native method not found: com.ishow.scan.zbar.ZbarManager.decode:([BIIZIIII)Ljava/lang/String;

            at com.ishow.scan.zbar.ZbarManager.decode(Native Method)

            at com.ishow.scan.decode.DecodeHandler.decode(DecodeHandler.java:58)

            at com.ishow.scan.decode.DecodeHandler.handleMessage(DecodeHandler.java:39)

            at android.os.Handler.dispatchMessage(Handler.java:107)

            at android.os.Looper.loop(Looper.java:194)

            at com.ishow.scan.decode.DecodeThread.run(DecodeThread.java:45)

 

无论你怎么搞,它就是报这个错误,让人很烦恼,本人开始使用Android studio,开始不懂如何导入动态库文件,毕竟Android studio不同于eclipse,在libs目录下放.so文件是没有用的,于是在Q群那里求救,终于有所收获,整理了一下,顺便在这里跟读者分享。

 

第一种方法:(最简单的方法)

在main目录下创建一个文件夹,文件夹名称:jniLibs,然后把我们的动态库文件导入到该文件夹下面,如图:

 

这样就可以把.so动态库文件导入到了Android studio。可是不管我怎么运行,就是报上面的java.lang.UnsatisfiedLinkError异常,我开始怀疑我导入的动态库文件,Android studio是不是无法找到,但按理说如果我的推断错误的话,应该不是报这个错误。于是我继续查找导入动态库文件到Android studio的方法,黄天不负有心人,我又学到了一种方法,

该方法主要有以下几个步骤:

1.在Windows下创建一个文件夹,文件夹名称lib

2.将动态库文件拷贝到lib目录下,如图,armeabi目录下存放.so文件

3.使用zip打包lib文件夹,然后重命名:armeabi.jar

4.把armeabi.jar拷贝到Android studio项目的libs目录下,即可

 

咨询了一下第三方提供so库的工作人员,回复说NeteaseMusicUtils类的包名一定要是com.netease.cloudmusic.utils。原因是JNI接口Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit中,com.netease.xtc.cloudmusic.utils代表的是package name,NeteaseMusicUtils则是class name。 
而第三方提供so库的工作人员的c文件的定义JNI接口为Java_com_netease_cloudmusic_utils_NeteaseMusicUtils_nativeInit,即:package name必须为:com.netease.cloudmusic.utils,而class name必须为 NeteaseMusicUtils。 
也就是说,我们.so中函数声明涉及到的package name和class name与调用它的package name和class name不符。因此我们要改变我们工程中的package name和class name。使其与.so文件中函数签名提示的一致,在这个类中加入native方法的声明。
 

通过了第二种方法完成了导入动态库文件到Android studio了,可是运行时还是出现了java.lang.UnsatisfiedLinkError异常,无奈之下,我以为是Android studio搞的鬼,可能我不熟悉Android studio。可是当我切换到eclipse,新建一个项目,继续完成我的工作(扫描二维码的项目),一切工作准备好后,运行项目,还是出现java.lang.UnsatisfiedLinkError异常,我快要疯了。于是我静下来思考:不可能eclipse和Android studio都会出现java.lang.UnsatisfiedLinkError,除非一开始我就一直走进一个错误的“圈套”。不错,问题终于搞清楚了,问题一定是加载库文件的那个类。于是经过进一步探索,运来是存放库文件的包名我写错了,这个包名不能随便命名,必须严格按照库文件里面的Android.mk指定的包名。于是我把包名该为:com.zbar.lib(原先com.ishow.org.zbar时一直报错),把包名改回来后,运行,哈哈,问题终于解决了!

 

  1. 确保包名正确
    Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
    这篇文章,主要是java文件包名不正确造成的,我使用的是第三方打包提供的jar和so文件,所以包名问题不存在,况且使用厂家的demo不存在此问题,所以问题应该是公司代码和厂家代码冲突所致。

  2. 确保lib下个目录,so文件数量一致
    关于android某些手机java.lang.UnsatisfiedLinkError: No implementation found for ......的问题

    java.lang.UnsatisfiedLinkError_第1张图片

    image.png


    将apk解压后查看lib,发现果然so目录文件不一致。libBugly.so在5个目录(腾讯bugly使用的so库),armeabi下,是厂家提供的so库。

     

解决途径

  1. 提供armv7编译的libA.so放入armeabi-v7a下,补齐各架构所需要的SO。
  2. 把armeabi-v7a目录去掉,默认armv7下也能使用armeabi下的SO。

如上是Bugly官网提供的解决方案。

  1. 厂家无法提供so,抛弃;
  2. 去掉armeabi-v7a等其他目录。可是bugly是使用gradle依赖的方式,默认就会加载所有so文件。

终极方案

在主模块的build.gradle文件,添加如下语句。

    defaultConfig {
        ...
        ndk {
            //设置支持的SO库架构
            abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
        }
    }

重新编译apk,运行,错误不见了,解压apk,查看lib

 

java.lang.UnsatisfiedLinkError_第2张图片

image.png

 

只有armeabi下面存在so文件,问题解决。

 

参考:https://segmentfault.com/a/1190000004165841

 

 

你可能感兴趣的:(Android开发)