Android App 瘦身总结 第二章 jni动态库及cpu兼容

##Android进阶之路系列:[http://blog.csdn.net/column/details/16488.html](http://blog.csdn.net/column/details/16488.html)

在前一章主要分析了图片资源部分的优化(http://www.jianshu.com/p/f22519065fce),这一章重点分析jni动态库部分。

由于我们的app业务较复杂,存在地图定位、图片处理、第三方浏览器内核等功能,这些功能都不可避免的引入了jni动态库 ——  ".so"文件。

我们知道jni动态库是用c\c++编写,目的是利用native层在运算等方面的优势提高应用性能。但是随着业务的增多,越来越多的jni动态库的加入就会导致这部分膨胀并占据很大一部分空间。

以百度地图为例,只使用基础地图和定位功能,每种平台下的几个.so文件加起来有2M多,如果将所有平台加入就会有10M多。

解决动态库的问题,要从几点着手:

一、利弊分析,按需引用

从两个例子来说。

(1)我们app中的图片处理业务,早期采用了一套第三方库。但是经过几次迭代业务稳定下来后,我们发现大部分功能都已经变了,绝大多数处理可以在Java层进行也不影响性能,而唯一的裁剪功能可以使用一套更加精致的库来替换,因为原来的第三方库是一套非常完整的图片解决方案,90%以上的功能我们都用不上。

(2)使用百度地图,可以在平台上根据app需要的功能定制动态库,没必要将所有功能一起打包进app

上面两个例子说明,在预开发阶段,我们要明确所需,以最小的代价完成功能;在迭代过程中,我们要持续的审视app各项业务功能,根据变更及时调整。

这点很难总结出具体方法,需要大家对业务功能深入理解,多思考分析。

二、平台兼容

Android系统中有以下几种平台:ARMv5,ARMv7,x86 ,MIPS ,ARMv8,MIPS64和x86_64。分别对应:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64

需要考虑下面几点:

(1)兼容关系

它们之间的兼容关系是:x86、x8664、armeabi-v7a、arm64-v8a都支持armeabi,但是x86设备不保证100%不发生crash,特别是对旧设备;64位(arm64-v8a, x8664, mips64)能够运行32位的函数库,但无法得到64位优化过的性能。

(2)占有率

目前android设备中以arm系列处理器为主流;x86系列处理器占有率较少,其中微软旗下的Lumia系列上使用较多,另外在部分平板设备上有使用;MIPS系列处理器占有率极少,这个处理器主要用在嵌入式。

由于arm是主流甚至成为标准,x86和mips处理器会通过一个特殊的转换软件去兼容arm指令集。

(3)性能优化

除了上面提到的64位处理器的相对于32位的优化,另外还有arm-v7处理器所支持的硬件浮点运算,arm虽然兼容但是也会损失性能。

这部分优化就需要我们根据自身app的功能、用户分析等方面全面去考虑。

比如MIPS设备,根据我们的统计没有用户使用这类cpu,可预测的时间内也不会超过万分之一,而且还有兼容性存在,所以我们果断忽略了这部分。

比如x86设备,根据统计我们用户中这类CPU占有率少于万分之一,同样短期内不会增长,在一些x86机器上测试通过后我们也选择忽略。

至于arm系列,由于地图等功能的存在,对运算等功能的性能要求较高,所以我们全部保留了。

如果你的app中动态库没有使用浮点运算或64位优化的相关功能,可以考虑去掉armeabi-v7a、arm64-v8a。

使用gradle可以选择打包时只打包某几个平台的动态库,这也解决了使用gradle依赖引入的lib中的动态库无法清除的问题,具体代码如下:

android {

    ...

    defaultConfig {

        ... 

        ndk {

            // 设置支持的 SO 库构架,注意这里要根据你的实际情况来设置

            abiFilters 'armeabi'// 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'

        }

注意需要在gradle.properties中添加android.useDeprecatedNdk=true

一定要注意保留的平台对应的目录下包含了全部需要的动态库!

注:目前国内主流的app中基本上只保留了armeabi或armeabi-v7a,不过他们应该对这些动态库重新编译过,大家有兴趣可以研究参考下。

三、动态加载

如果存在特别大的动态库,可以考虑不打包进apk,通过预下载动态延迟加载来实现,因为一般使用动态库的功能都不是启动app就需要的。

四、总结

动态库部分差不多就这些情况,这里没有什么便捷的工具来使用,更主要是靠我们对业务熟悉程度进行全面细致的分析权衡。下一章会从代码方面来进行部分探讨。

##Android进阶之路系列:[http://blog.csdn.net/column/details/16488.html](http://blog.csdn.net/column/details/16488.html)

你可能感兴趣的:(Android App 瘦身总结 第二章 jni动态库及cpu兼容)