Android中so文件加载问题

前言-现在市面主流的手机架构
  • x86/x86_64:这种架构手机包含由Intel提供的指令集转码工具,实现了对arm的兼容,使用这种架构的手机市场占有率很低。
  • mips/mips64:极少手机使用这种架构,有兴趣可以自行百度。
  • armeabi ARM v5:相当老旧的版本,缺少对浮点数计算的硬件支持,需要大量计算时有性能瓶颈。
  • armeabi-v7a ARM v7:现在市面上主流版本,比如骁龙、麒麟处理器等大部分处理器采用这种架构。
  • arm64-v8a ARM v8 :64位的
问题1 cannot find “libxxx.so”

原因分析

一. 存放路径不对,默认是放在src/jniLibs,而手动指定目录后放错了位置。

Android Studio一般把so文件放在jnilibs目录下对应的框架名文件夹下(比如:armeabi、armeabi-v7a、arm64-v8a)。你也可以自己定义jni的目录。

如下在工程级别的gradle下设置了路径myJniLibs,那文件就要放到这个目录下对应架构文件里。

 sourceSets.main {
        jniLibs.srcDirs = ['src/main/myJniLibs']
    }

二. 由于不同框架下的so文件名称不同,造成的找不到。
一般情况下,一组so文件名称都是一样的,放在不同的架构文件夹下。使用的时候直接通过一行代码就能加载。

  //放到库文件的so文件→libxxx.so
  System.loadLibrary("xxx");

但是对于情况2则要手动判断cpu架构,以ffmpeg的so文件为例,代码如下

try {
		  //判断cpu架构,拿到不同的so文件
          if (Build.class.getField("CPU_ABI").get(null).toString().startsWith("arm64-v8a")) {
              System.loadLibrary("ffmpeg-squirrel-arm64-v8a");
          } else {
              System.loadLibrary("ffmpeg-squirrel-armeabi-v7a");
          }
      } catch (IllegalAccessException e) {
          e.printStackTrace();
      } catch (NoSuchFieldException e) {
          e.printStackTrace();
      }

三. 32位系统的手机不会报错,64位系统的手机报错

“xxx.so” is 32-bit instead of 64-bit

分析:项目中使用了多个第三方的sdk。有的sdk提供了32位和64位的so文件,有的sdk只提供了32位的so文件。当使用64位手机去拿某个只提供了32位so文件sdk的库文件的时候,由于只会去64位架构文件下找,但是找不到(64位的文件夹存在,但是里面没有我要的这个so文件)。

解决办法:

  1. 把64位的文件夹全删了,因为向下兼容,就回去32位文件下找。
  2. 自己编译64位的so,或者叫第三方提供。(一般源码找不到,就只能找第三方弄)
问题2 java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad

加载so文件的代码所在的类,需要和so文件实现所在的类是同一个包名,不然它找不到so文件中native方法的实现。

出错原因:打so包的那个ndk-build的配置文件的packageName和加载so文件那个类的包名不一致。

后话-打出一个so文件

不管是Eclipse还是AndroidStudio,只要配置了ndk的环境变量(Linux系统忽略,Windows在系统变量的Path里添加你的ndk-bundle文件目录),就可以打出so。

  1. 打开命令行。切到jni所在目录。
  2. Android.mkApplication.mk2个文件配置一下。
  3. 命令行输入ndk-build命令。

例子
1、Application.mk

//打出所有类型的so,也可以写几个你需要的  APP_ABI := armeabi,armeabi-v7a,arm64-v8a
APP_ABI := all 

2、Android.mk
这个文件比较复杂,就不贴了。大概就是定义路径的变量,so包名称,本地src路径下的一些".c"文件等。有兴趣的可以自行百度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值