求助jni 加载so库的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求助jni 加载so库的问题相关的知识,希望对你有一定的参考价值。

参考技术A 原因很简单,不同CPU架构的设备需要用不同类型SO库(从文件名也可以猜出来个大概嘛 ╮( ̄▽ ̄")╭)。

记得还在学校的时候,提及ARM处理器时,老师说以后移动设备的CPU基本就是ARM类型的了。老师不曾欺我,早期的android系统几乎只支持ARM的CPU架构,不过现在至少支持以下七种不同的CPU架构:ARMv5,ARMv7,x86,MIPS,ARMv8,MIPS64和x86_64。每一种CPU类型都对应一种ABI(Application Binary Interface),“armeabi-v7a”文件夹前面的“armeabi”指的就是ARM这种类型的ABI,后面的“v7a”指的是ARMv7。这7种CPU类型对应的SO库的文件夹名是:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。

不同类型的移动设备在运行APP时,需要加载自己支持的类型的SO库,不然就GG了。通过 Build.SUPPORTED_ABIS 我们可以判断当前设备支持的ABI,不过一般情况下,不需要开发者自己去判断ABI,Android系统在安装APK的时候,不会安装APK里面全部的SO库文件,而是会根据当前CPU类型支持的ABI,从APK里面拷贝最合适的SO库,并保存在APP的内部存储路径的 libs 下面。(这里说一般情况,是因为有例外的情况存在,比如我们动态加载外部的SO库的时候,就需要自己判断ABI类型了。)

动态加载so文件

在开发过程中,经常会用到第三方库,比如地图、视频、文档编辑、图表之类。依赖这些库,需要添加其SDK,有时需要用到jni层的So文件,比如百度地图等。

 

那么问题来了,如果两个不同的库之间的so文件发生冲突这么办?

 

比如:单独添加地图的库,运行没有问题。单独添加一个视频库,运行没有问题。但两者同时添加,其中一个库在init的时候报错。这当然和第三方库的开发水平有很大关系,但我们怎么解决这个问题呢?这就用到动态加载的方法。

 

这是原先的静态加载方法,将所有依赖库的so文件全部一股脑的放进armeabi文件夹即可。

 

动态加载的方法,我将冲突的so文件放在assets文件夹中

 

这里需要注意的是:动态加载so的文件只能放在两个地方:1. lib文件夹中,即对应Android Studio中的jniLibs文件夹。2. 本地data/data/package数据目录下。 所以,当应用第一次启动的时候,必须将我们放在assets文件夹中的so文件拷贝乳本地数据目录下。

 

 

技术分享

 

当然,上面这个方法是将so文件放在程序的assets文件夹。另一种方法是:也可以从网络上下载,放入本地数据目录下。这样的好处是不仅减小的了apk的大小,而且可以随时使用最新的依赖库,这也是动态加载的最多得用途之一。

以上是关于求助jni 加载so库的问题的主要内容,如果未能解决你的问题,请参考以下文章

tomcat下部署多应用加载公共JNI动态库的解决方案

求助:libz.so.1:no version information available

Android JNI开发三: SO库的使用

求助:libz.so.1:no version information available

Android JNI开发二: SO库的使用

求助:QtCreator创建的QtGui应用中,如何调用libxx.so中的C函数。