安卓so包、aar、依赖项目的使用

一.添加aar

1.1什么是aar

AARGoogleAndroid Studio专门推出的一种库文件格式,Eclipse没办法像使用jar那样直接使用AAR文件,但是我们可以使用AAR里面的文件快速创建一个Eclipse Library项目,然后在我们的项目中引用即可。

1.2aar和jar包的区别

*.jar:只包含了class文件与清单文件,不包含资源文件,如图片、布局等所有res中的文件。
*.aar:包含所有资源,class以及res资源等全部文件。

如果你只需要一个简单的类库,那么使用生成的*.jar文件即可;如果你需要的是一个UI库,包含一些自己写的控件布局以及字体等资源文件,那么就只能使用*.aar文件。将代码打包成aar文件可以在一定程度上加快Android Studio的加载速度,尤其是将Module打包成aar文件提升的效果会更加显著。


1.3aar在在Android Studio中的使用

  1. 将要集成的AAR文件拷贝到工程的libs目录下;

  2. 在项目工程的build.gradle配置文件中做以下配置:

如下图添加:

repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies {
 implementation(name: 'IMeasureSDK', ext: 'aar')
}

二.添加So包

2.1什么是so包

Android 系统本质是一个经过改造的 Linux 系统,so库是Linux系统上使用的共享库(类似windows上的dll)。最早,Android 系统只支持 ARMv5 的 CPU 构架,随着 Android 系统的发展,又加入了 ARMv7 (2010), x86 (2011), MIPS (2012), ARMv8, MIPS64 和 x86_64 (2014)。每一种 CPU 构架,都定义了一种 ABI(Application Binary Interface),ABI 决定了二进制文件如何与系统进行交互。

详情请看我之前的文章:https://blog.csdn.net/xxdw1992/article/details/87157582

2.2在build文件中配置

defaultConfig {
        ndk {
            abiFilters "armeabi", "armeabi-v7a","arm64-v8a", "x86", "x86_64", "mips", "mips64"
        }
    }



//    读取libs中的so文件
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

2.3为什么要设置ndk的abiFilters

其实这个可以不设置,这样编译时,就会将项目里所有依赖资源包里的so库都打到最终的apk里。

但是有些平台,我们是不需要支持的,如果不删除的话,apk就臃肿了。如果那些so库是我们自己编译出来的,那可以直接在工程中删除对应so文件,但是如果是第三方提供的,就不好删除了,所以就需要使用abiFilters来过滤了。

如果需要针对不同的平台出不同的包,可以在productFlavors里进行设置,可参考文章:https://blog.csdn.net/hknock/article/details/76034125

armeabi、armeabi-v7a、arm64-v8a的兼容性问题

看上上面的描述,以为新增一个so库文件可以随便根据需要适配的目录放,就错了。如果你有库文件在armeabi里有,但是armeabi-v7a目录下没有,那么运行在V7a的架构时,就会出现找不到so库文件的情况。具体描述参照:Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题

正确的做法

  1. 当前市面绝大多数是arm的CPU,而且都是V7架构的了,所以可以保留armeabi或者armeabi-v7a即可。
  2. 如果仅保留armeabi-v7a,而有些第三方包未提供v7a的包,则可以将对应armeabi包拷贝到armeabi-v7a。
  3. 如果同时保留armeabi和armeabi-v7a,则需要保证两个目录下的so库文件数相同。

安卓开发技术分享: https://www.jianshu.com/p/442339952f26

2.4常见问题

2.4.1gradle文件中添加: sourceSets { main { jniLibs.srcDirs = ['libs'] } }会报错误

如果有jniLibs目录就不需要设置Jni so文件路径

三.添加依赖项目

现在settings.gradle添加依赖项目的名字

选中Module Dependency勾选确定就可以添加依赖

四.添加依赖包

输入你要添加的依赖包,搜索添加即可,右边是版本号

五.新建jniLibs文件夹

5.1添加jniLibs.srcDirs = ['libs']

在moudle的build文件中添加

在bulidTypes {} 结束后添加此段代码,

sourceSets{  

      main{  

          jniLibs.srcDirs=['libs']  

      }  

  }  

记住该段代码是包含在android{} 里头的

5.2新建文件夹

找到如下路径app--src--main,右击main 文件夹 ,选择New ,新建Directory

然后文件夹命名jniLibs,往里头添加so 文件后就在目录中就能像res文件夹 显示了

或者直接如下创建:

六.Android 找不到so库(系统非公开库)文件

 

导入第三方sdk,运行报错:
java.lang.UnsatisfiedLinkError: dlopen failed: library “libskia.so” not found。
一直以为是arr内部引用的私有so库文件出的问题,搜索了一下发现libskia.so是系统库文件(其他常用系统so库 libandroid_runtime.so、libcutils.solibcrypto.so ,libssl.so),从 Android 7.0 开始,系统阻止应用动态链接非公开 NDK 库
解决方法:

  1. targetSdkVersion 设置为23及23以下
  2. 将so文件复制到项目armeabi-v7a文件夹下

链接:

https://blog.csdn.net/lihuapinghust/article/details/45825063

https://www.cnblogs.com/janehlp/p/7473240.html

https://zhuanlan.zhihu.com/p/21359984

七.so包的拷贝策略

  1. 1)针对 armeabi 和 armeabi-v7a 两种 ABI

    方法1:由于 armeabi-v7a 指令集兼容 armeabi 指令集,所以如果损失一些应用的性能是可以接受的,同时不希望保留库的两份拷贝,可以移除 armeabi-v7a 目录和其下的库文件,只保留 armeabi 目录;比如 apk 使用第三方的 so 只有 armeabi 这一种 abi 时,可以考虑去掉 apk 中 lib 目录下 armeabi-v7a 目录。

    方法2:在 armeabi 和 armeabi-v7a 目录下各放入一份 so;

  2. 2)针对x86

    目前市面上的x86机型,为了兼容 arm 指令,基本都内置了 libhoudini 模块,即二进制转码支持,该模块负责把 ARM 指令转换为 X86 指令,所以如果是出于 apk 包大小的考虑,并且可以接受一些性能损失,可以选择删掉 x86 库目录, x86 下配置的 armeabi 目录的 so 库一样可以正常加载使用;

  3. 3)针对64位 ABI

    如果 app 开发者打算支持64位,那么64位的 so 要放全,否则可以选择不单独编译64位的 so,全部使用32位的 so,64位机型默认支持32位 so 的加载。比如 apk 使用第三方的 so 只有32位 abi 的 so,可以考虑去掉 apk 中 lib 目录下的64位 abi 子目录,保证 apk 安装后正常使用。

参考网址:http://crash.163.com/#news/!newsId=5

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值