美文网首页Android开发Android开发Android开发经验谈
为何Twitter区别于微信、淘宝,只使用了armeabi-v7

为何Twitter区别于微信、淘宝,只使用了armeabi-v7

作者: 遛狗的程序员 | 来源:发表于2017-03-23 22:23 被阅读909次

    最近在研究APP瘦身,碰巧又遇到armeabi、armeabi-v7a、arm64-v8a等ABI相关的知识点,决心记录下来以作分享。

    目前现状

    首先我们分析下国内的淘宝、微信,以及国外的Facebook、Twitter都使用了哪些ABI。

    我们对这4家APK进行Analyze,可以发现Facebook和Twitter只使用了armeabi-v7a,而微信和淘宝只使用了armeabi,分析结果如下图所示:


    WechatIMG17.jpeg

    大厂并没有按照我们的理解使用不同的ABI针对不同的CPU?其实笔者发现携程、饿了么、百度糯米都是只使用了armeabi,阿里系的淘票票使用了armeabi、x86(如果你有兴趣,可以通过爬取分析一下应用市场的前100名都使用了哪些ABI)。

    知识点回顾

    首先,我们来看下Google老大哥是怎么介绍的ABI的,翻译官方文档:

    不同 Android 手机使用不同的 CPU,因此支持不同的指令集

    CPU 与指令集的每种组合都有其自己的应用二进制界面(或 ABI)

    ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互

    您必须为应用要使用的每个 CPU 架构指定 ABI

    表 1. ABI 和支持的指令集。

    WechatIMG18.jpeg

    各版本分析如下:

    • mips / mips64: 极少用于手机可以忽
    • x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的
    • armeabi: ARM v5 这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈
    • armeabi-v7a: ARM v7 目前主流版本
    • arm64-v8a: 64位支持

    具体含义

    如果你基础比较好的话,看完Google老大哥的介绍的话,就明白了:不同的 CPU 支持不同的指令集。当我们需要我们APP支持尽可能多的不同CPU的时候,只需要将不同版本的so文件放置在不同的目录下,APK安装运行的时候会根据自己需要而自己选取。

    但是这样却带来一个问题,APK文件较大,影响用户下载。

    那我们是否可以只放置一些呢?

    必然可以!

    我们继续看Google老大哥是怎么说的:

    • 为实现最佳性能,应直接针对主要 ABI进行编译。例如,基于 ARMv5TE的典型设备只会定义主要 ABI:armeabi
    • 相反,基于ARMv7的典型设备将主要ABI定义为armeabi-v7a,而将辅助ABI定义为armeabi,因为它可以运行为每个ABI生成的应用原生二进制文件
    • 许多基于x86的设备也可行 armeabi-v7a 和 armeabi NDK 二进制文件
    • 对于这些设备,主要ABI将是 x86,辅助ABI是armeabi-v7a
    • 基于 MIPS的典型设备只定义主要ABI:mips
    • 安装应用时,软件包管理器服务将扫描APK,查找以下形式的任何共享库:
      lib/<primary-abi>/lib<name>.so
      
    • 如果未找到,并且您已定义辅助 ABI,该服务将扫描以下形式的共享库
      lib/<secondary-abi>/lib<name>.so
      
    • 找到所需的库时,软件包管理器会将它们复制到应用的 data 目录 (data/data/<package_name>/lib/) 下的/lib/lib<name>.so

    分析

    上面说,如果根本没有共享对象文件,应用也会构建并安装,但在运行时会崩溃。所以有时候我们遇到

    Exception:Java.lang.UnsatisfiedLinkError: dlopen failed: library “/***.so” not found 
    

    此时我们首先要想到的,是不是so文件没有放置,或者是在armeabi放置a.so,b.so,但是在armeabi-v7a只放置了b.so,没有放置a.so。

    这里强调一下:虽然arm64-v8a是可以向下兼容的,但是也是兼容的有限制的:

    其下有armeabi-v7a,armeabi ;armeabi-v7a向下兼容armeabi。对于一个cpu是arm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,先看有没有arm64-v8a文件夹,如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常; 如果有arm64-v8a文件夹,那么就去找特定名称的.so文件。
    如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。

    注意:

    1. 如果没有找到,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。
    2. 如果你的项目用到了第三方依赖,如果只保留一个ABI的时候,建议在Build中加入ndk.abiFilters
    3. 例如:第三方aar文件,如果这个sdk对abi的支持比较全,可能会包含armeabi、armeabi-v7a、x86、arm64-v8a、x86_64五种abi,而你应用的其它so只支持armeabi、armeabi-v7a、x86三种,直接引用sdk的aar,会自动编译出支持5种abi的包。但是应用的其它so缺少对其它两种abi的支持,那么如果应用运行于arm64-v8a、x86_64为首选abi的设备上时,就会==crash==了哦。
    defaultConfig {  
        ndk {  
            abiFilters "armeabi"// 指定ndk需要兼容的ABI(这样其他依赖包里x86,armeabi,arm-v8之类的so会被过滤掉) 
        }  
    }  
    

    总结

    1. 如果你希望APK针对不同CPU有不同的版本,你可以使用胖二进制的方式,在不同的目录下面放置不同的so文件。这样兼容性更广、性能好些,但是APK大些;

    2. 如果你希望APK小一些,你可以像淘宝、微信、FaceBook、Twitter一样,一个api闯天下,至于选择armeabi、armeabi-v7a看你市场用户了。目前主流手机cpu多属于armeabi-v7a;

    3. 当然,你也可以动态检查系统环境,如果是x86就去下载相关库,然后加载......这样可以减少apk体积。


    作者:微信公众号添加公众号-遛狗的程序员 ,或者可以扫描以下二维码关注相关技术文章。

    qrcode_for_gh_1ba0785324d6_430.jpg

    当然喜爱技术,乐于分享的你也可以可以添加作者微信号:

    WXCD.jpeg

    相关文章

      网友评论

        本文标题:为何Twitter区别于微信、淘宝,只使用了armeabi-v7

        本文链接:https://www.haomeiwen.com/subject/qpbinttx.html