前言:在项目中我们不免很多时候需要集成第三方SDK,比如:环信,友盟,七牛云等等,一般来说集成以及初始化SDK按照第三方SDK官方文档来基本上就没什么问题。最近在项目中加载so文件的时候遇到一些问题,在此记录下来希望可以帮助到大家.
so文件
如果说对so文件分类的话大致就64和32位so文件了,在android的libs或者jnilibs目录下你可能会发现
这几种存放so文件的目录。what?这么多目录到底加载哪个目录下的so文件呐?骚年别急嘛。老弟就给你举个列子.
android资源文件加载:在最古老的屏幕适配我们都会创建各种不同分辨率的资源文件,然后运行在真机上系统会自适应加载对应的资源文件,这么多不同分辨率资源文件当然不可能全部加载。因此我们就明白上面几个目录并不是全部都要加载。
Android设备如何加载.so文件
当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。不同CPU架构的Android手机加载时会在libs下找自己对应的目录,从对应的目录下寻找需要的.so文件;如果没有对应的目录,就会去armeabi下去寻找,如果已经有对应的目录,但是如果没有找到对应的.so文件,也不会去armeabi下去寻找了。
以x86设备为例,x86设备会在项目中的 libs文件夹寻找是否含有x86文件夹,如果含有x86文件夹,则默认为该项目有x86对应的so可运行文件,只有x86文件夹而文件夹下没有so,程序运行也是会出现findlibrary returned null的错误的;如果工程本身不含有x86文件夹,则会寻找armeabi或者armeabi-v7a文件夹,兼容运行。以armeabi-v7a设备为例,该Android设备当然优先寻找libs目录下的armeabi-v7a文件夹,同样,如果只有armeabi-v7a文件夹而没有 so也是会报错的;如果找不到armeabi-v7a文件夹,则寻找armeabi文件夹,兼容运行该文件夹下的so,但是不能兼容运行x86的so。所以项目中如果只含有x86的so,在armeabi和armeabi-v7a也是无法运行的。以上就是不同CPU架构运行时加载so的策略。
那么这几个文件夹到底是什么意思呐?shut,别急骚年...往下看...
armeabi-v7a: 第7代及以上的 ARM 处理器。目前大部分Android设备都使用它.
arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一。
armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多。
x86: 平板、模拟器用得比较多。
Gradle配置加载so文件
上面讲解了加载so文件的各个文件夹,现在说下gradle里面配置加载so文件。
- 配置加载指定so文件夹 ndk { abiFilters 'arm64-v8a','armeabi-v7a' } 这个配置起什么作用呐?就是让系统去加载arm64-v8a,armeabi-v7a文件夹里面的so文件,个人建议不要在此配置,因为有的第三方SDK并不是支持所有的文件夹的so文件,比如说:有的不支持armeabi,如果你指定去加载了就容易出现问题。当然如果觉得这样会增大apk体积,那么建议仔细按照官方SDK文档来.
配置so文件路径
这一步比较简单但是也容易忘记的。
sourceSets { main() {
jniLibs.srcDirs = ['libs']
}
}
温馨提示:极少数第三方SDK需要添加其他配置,比如环信SDK集成(这里我就直接贴文档):
1. 用户集成 SDK 后使用 HttpClient 报错
建议将SDK升级到3.6.8以上版本,SDK3.6.8以后版本移除了apache library。
3.6.8版本之前的版本请按照下面进行配置:
- Android 6.0及以上版本需要在module-level/build.gradle
android block中添加:
android {
//use legacy for android > 6.0
useLibrary 'org.apache.http.legacy'
}
- Android 9.0还需在AndroidManifest.xml
的application
标签中添加:
<application>
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>
2. Android 9.0上强制使用https的问题
表现:会出现出现UnknownServiceException: CLEARTEXT communication to localhost not permitted by network security policy
或者IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
报错
解决办法可以参考:StackOverFlow,也可以直接在AndroidManifest.xml
文件的application
标签中设置android:usesCleartextTraffic=“true”
<application
android:usesCleartextTraffic="true" >
</application>