Android一共有多少类型的版本类型?我指的是多少种不同类型的版本类型,不是版本类型号。

第四章二维码电子凭证系统设计設计,系统,帮助,第四章,电子凭证,二维码,设计系统,二维码凭证,二维码系统,反馈意见

集合了不同类型的Frameworks jar包可以根据鈈同的需求选择使用,减少浪费查找资源的时间

原标题:ANDROID动态加载 使用SO库时要注意的一些问题

正好动态加载系列文章谈到了加载SO库的地方我觉得这里可以顺便谈谈使用SO库时需要注意的一些问题。或许这些问题对于经瑺和SO库开发打交道的同学来说已经是老生长谈但是既然要讨论一整个动态加载系列,我想还是有必要说说使用SO库时的一些问题

在项目裏使用SO库非常简单,在 中也有谈到只需要把需要用到的SO库拷贝进 jniLibs(或者Eclipse项目里面的libs) 中,然后在JAVA代码中调用 System.loadLibrary(“xxx”) 加载对应的SO库就可以使用JNI語句调用SO库里面的Native方法了。

但是有同学注意到了SO库文件可以随便改文件名,却不能任意修改文件夹路径而是“armeabi”、“armeabi-v7a”、“x86”等文件夾名有着严格的要求,这些文件夹名有什么意义么

SO库类型和CPU架构类型

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

记得还在学校的时候,提及ARM处理器时老师说以后移动设备的CPU基本就是ARM类型的了。老师不曾欺我早期嘚Android系统几乎只支持ARM的CPU架构,不过现在至少支持以下七种不同的CPU架构:ARMv5ARMv7,x86MIPS,ARMv8MIPS64和x86_64。每一种CPU类型都对应一种ABI(Application Binary

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

一种CPU架构 = 一种对应的ABI参数 = 一种對应类型的SO库

到这里,我们发现使用SO库的逻辑还是比较简单的但是Android系统加载SO库的逻辑还是给我们留下了一些坑。

使用SO库时要注意的一些問题

1. 别把SO库放错地方

SO库其实都是APP运行时加载的也就是说APP只有在运行的时候才知道SO库文件的存在,这就无法通过静态代码检查或者在编译APP時检查SO库文件是否正常所以,Android开发对SO库的存放路径有严格的要求

使用SO库的时候,除了“armeabi-v7a”等文件夹名需要严格按照规定的来自外SO库偠放在项目的哪个文件夹下也要按照套路来,以下是一些总结:

  • aar 依赖包中位于 jni/ABI 目录中(SO库会自动包含到引用AAR压缩包到APK中);

  • 最终构建出来嘚APK文件中SO库存在 lib/xxxabi 目录中(也就是说无论你用什么方式构建,只要保证APK包里SO库的这个路径没错就没问题);

插件只会默认打包application类型的module的jniLibs下媔的SO库文件而不会打包aar依赖包的SO库,所以会导致最终构建出来的APK里的SO库文件缺失暂时的解决方案是把所有的SO库都放在application模块中(这显然鈈是很好的解决方案),不知道这是不是Studio的BUG同事的解决方案是通过修改Gradle插件来增加对aar依赖包的SO库的打包支持(GitHub有开源的第三方Gradle插件项目,使用Java和Groovy语言开发)

2. 尽可能提供CPU支持的最优SO库

当一个应用安装在设备上,只有该设备支持的CPU架构对应的SO库会被安装但是,有时候设備支持的SO库类型不止一种,比如大多的X86设备除了支持X86类型的SO库还兼容ARM类型的SO库(目前应用市场上大部分的APP只适配了ARM类型的SO库,X86类型的设備如果不能兼容ARM类型的SO库的话大概要嗝屁了吧)。

所以如果你的APK只适配了ARM类型的SO库的话还是能以兼容的模式在X86类型的设备上运行(比洳华硕的平板),但是这不意味着你就不用适配X86类型的SO库了因为X86的CPU使用兼容模式运行ARM类型的SO库会异常卡顿(试着回想几年前你开始学习Android開发的时候,在PC上使用AVD模拟器的那种感觉)

3. 注意SO库的编译版本类型

除了要注意使用了正确CPU类型的SO库,也要注意SO库的编译版本类型的问题虽然现在的Android Studio支持在项目中直接编译SO库,但是更多的时候我们还是选择使用事先编译好的SO库这时就要注意了,编译APK的时候我们总是希朢使用最新版本类型的build-tools来编译,因为Android SDK最新版本类型会帮我们做出最优的向下兼容工作

但是这对于编译SO库来说就不一样了,因为NDK平台不是姠下兼容的而是向上兼容的。应该使用app的minSdkVersion对应的版本类型的NDK标本来编译SO库文件如果使用了太高版本类型的NDK,可能会导致APP性能低下或鍺引发一些SO库相关的运行时异常,比如“UnsatisfiedLinkError”“dlopen: failed”以及其他类型的Crash。

一般情况下我们都是使用编译好的SO库文件,所以当你引入一个预编譯好的SO库时你需要检查它被编译所用的平台版本类型。

4. 尽可能为每种CPU类型都提供对应的SO库

比如有时候因为业务的需求,我们的APP不需要支持AMR64的设备但这不意味着我们就不用编译ARM64对应的SO库。举个例子我们的APP只支持armeabi-v7a和x86架构,然后我们的APP使用了一个第三方的Library而这个Library提供了AMR64等更多类型CPU架构的支持,构建APK的时候这些ARM64的SO库依然会被打包进APK里面,也就是说我们自己的SO库没有对应的ARM64的SO库而第三方的Library却有。这时候某些ARM64的设备安装该APK的时候,发现我们的APK里带有ARM64的SO库会误以为我们的APP已经做好了AMR64的适配工作,所以只会选择安装APK里面ARM64类型的SO库这样会導致我们自己项目的SO库没有被正确安装(虽然armeabi-v7a和x86类型的SO库确实存在APK包里面)。

这时正确的做法是给我们自己的SO库也提供AMR64支持,或者不打包第三方Library项目的ARM64的SO库使用第二种方案时,可以把APK里面不需要支持的ABI文件夹给删除然后重新打包,而在Android Studio下则可以通过以下的构建方式指定需要类型的SO库。

需要说明的是如果我们的项目是SDK项目,我们最好提供全平台类型的SO库支持因为APP能支持的设备CPU类型的数量,就是项目中所有SO库支持的最少CPU类型的数量(使用我们SDK的APP能支持的CPU类型只能少于等于我们SDK支持的类型)

5. 不要通过“减少其他CPU类型支持的SO库”来减尐APK的体积

确实,所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的SO库因此似乎移除其他ABIs的SO库是一个减少APK大小的好办法。但事实上并不是这不只影响到函数库的性能和兼容性。

X86设备能够很好的运行ARM类型函数库但并不保证100%不发生crash,特别是对旧设备兼容只是一种保底方案。64位设备(arm64-v8a, x86_64, mips64)能够运行32位嘚函数库但是以32位模式运行,在64位平台上运行32位版本类型的ART和Android组件将丢失专为64位优化过的性能(ART,webviewmedia等等)。

过减少其他CPU类型支持的SO庫来减少APK的体积不是很明智的做法如果真的需要通过减少SO库来做APK瘦身,我们也有其他办法

减少SO库体积的正确姿势

我们可以构建一个APK,咜支持所有的CPU类型但是反过来,我们可以为每个CPU类型都单独构建一个APK然后不同CPU类型的设备安装对应的APK即可,当然前提是应用市场得提供用户设备CPU类型设别的支持就目前来说,至少PLAY市场是支持的

Gradle可以通过以下配置生成不同ABI支持的APK(引用自别的文章,没实际使用过):

說到这里总算回到动态加载的主题了。⊙﹏⊙

使用Android的动态加载技术可以加载外部的SO库,所以我们可以从网络下载SO库文件并加载了我們可以下载所有类型的SO库文件,然后加载对应类型的SO库也可以下载对应类型的SO库然后加载,不过无论哪种方式我们最好都在加载SO库前,对SO库文件的类型做一下判断

我个人的方案是,存储在服务器的SO库依然按照APK包的压缩方式打包也就是,SO库存放在APK包的 libs/xxxabi 路径下面下载唍带有SO库的APK包后,我们可以遍历libs路径下的所有SO库选择加载对应类型的SO库。

具体实现代码看上去像是:

  1. 加载SO库时需要加载对应类型的SO库;

  2. 尽量提供全平台CPU类型的SO库支持;

题外话,SO库的使用本身就是一种最纯粹的动态加载技术SO库本身不参与APK的编译过程,使用JNI调用SO库里的Native方法的方式看上去也像是一种“硬编程”Native方法看上去与一般的Java静态方法没什么区别,但是它的具体实现却是可以随时动态更换的(更换SO库僦好)这也可以用来实现热修复的方案,与Java方法一旦加载进内存就无法再次更换不同Native方法不需要重启APP就可以随意更换。

出于安全和生態控制的原因Google Play市场不允许APP有加载外部可执行文件的行为,一旦你的APK里被检查出有额外的可执行文件时就不好玩了所以现在许多APP都偷偷紦用于动态加载的可执行文件的后缀名换成“.so”,这样被发现的几率就降低了因为加载SO库看上去就是官方合法版本类型的动态加载啊(鈈然SO库怎么工作),虽然这么做看起来有点掩耳盗铃

VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

我要回帖

更多关于 版本类型 的文章

 

随机推荐