• 初探Matrix Android ApkChecker


    背景#

    因为我所在的项目是做投放包,对安卓包的大小很敏感,经常会优化包的大小,所以想引入工具静态检测包大小,看能不能找到其中可以优化的地方,防患于未然。Matrix是微信终端自研和正在使用的一套APM(Application Performance Management)系统。 Matrix-ApkChecker作为Matrix系统的一部分,是针对android安装包的分析检测工具,根据一系列设定好的规则检测apk是否存在特定的问题,并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪。Matrix-ApkChecker以一个jar包的形式提供使用,通过命令行执行 java -jar ApkChecker.jar 即可运行。

    Matrix-ApkChecker的使用#

    在git上下载matrix-apk-canary-0.4.10.jar
    直接在命令行执行

    java -jar ApkChecker.jar
    

    即可以查看Matrix-ApkChecker的使用说明 (注意:下面所说的路径为完整路径,非相对路径)

    Matrix-ApkChecker的命令行参数比较多,主要包括global参数和option参数两类:

    • global
      --apk   输入apk文件路径(默认文件名以apk结尾即可)
      --mappingTxt   代码混淆mapping文件路径 (默认文件名是mapping.txt  --resMappingTxt   资源混淆mapping文件路径(默认文件名是resguard-mapping.txt  --input   包含了上述输入文件的目录(给定--input之后,则可以省略上述输入文件参数,但上述输入文件必须使用默认文件名)
      --unzip   解压apk的输出目录
      --output   输出结果文件路径(不含后缀,会根据format决定输出文件的后缀)
      --format   结果文件的输出格式(例如 html、json等)
      --formatJar   实现了自定义结果文件输出格式的jar包
      --formatConfig   对结果文件输出格式的一些配置项(json数组格式)
    

    global 参数之后紧跟若干个 Option,这些 Option 是可选的,一个 Option 表示针对 apk 的一个检测选项。

    • option参数
      • manifest 从AndroidManifest.xml文件中读取apk的全局信息,如packageName、versionCode等。
      • fileSize 列出超过一定大小的文件,可按文件后缀过滤,并且按文件大小排序
      --min   文件大小最小阈值,单位是KB
      --order   按照文件大小升序(asc)或者降序(desc)排列
      --suffix   按照文件后缀过滤,使用","作为多个文件后缀的分隔符
      
      • countMethod 统计方法数
      group   输出结果按照类名(class)或者包名(package)来分组
      
      • checkResProguard 检查是否经过了资源混淆 (AndResGuard)
      • findNonAlphaPng 发现不含alpha通道的png文件
      • checkMultiLibrary 检查是否包含多个ABI版本的动态库
      • uncompressedFile 发现未经压缩的文件类型(即该类型的所有文件都未经压缩)
      suffix   按照文件后缀过滤,使用","作为多个文件后缀的分隔符
      
      • countR 统计apk中包含的R类以及R类中的field count
      • duplicatedFile 发现冗余的文件,按照文件大小降序排序
      • checkMultiSTL 检查是否有多个动态库静态链接了STL
      • unusedResources 发现 apk 中包含的无用资源
      rTxt   R.txt文件的路径(如果在全局参数中给定了--input,则可以省略)
      ignoreResources   需要忽略的资源,使用","作为多个资源名称的分隔符
      
      • unusedAssets 发现apk中包含的无用assets文件
      • ignoreAssets 需要忽略的assets文件,使用","作为多个文件的分隔符
      • unstrippedSo 发现apk中未经裁剪的动态库文件

    除了直接在命令行中带上详细参数外,也可以将参数配置以 json 的格式写到一个配置文件中,然后在命令行中使用
    指定配置文件的路径。一个典型的配置文件格式如下:

    {
        "--apk": "/xxx",
        "--formatConfig": [
            {
                "group": [
                    {
                        "name": "Android System",
                        "package": "android"
                    },
                    {
                        "name": "java system",
                        "package": "java"
                    },
                    {
                        "name": "xxx",
                        "package": "com.xxx"
                    }
                ],
                "name": "-countMethod"
            }
        ],
        "--format": "mm.html,mm.json",
        "options": [
            {
                "name": "-manifest"
            },
            {
                "--suffix": "png, jpg, jpeg, gif, arsc",
                "--min": "10",
                "name": "-fileSize",
                "--order": "desc"
            },
            {
                "--group": "package",
                "name": "-countMethod"
            },
            {
                "name": "-checkResProguard"
            },
            {
                "--min": "10",
                "name": "-findNonAlphaPng"
            },
            {
                "name": "-checkMultiLibrary"
            },
            {
                "--suffix": "png, jpg, jpeg, gif, arsc",
                "name": "-uncompressedFile"
            },
            {
                "name": "-countR"
            },
            {
                "name": "-duplicatedFile"
            },
            {
                "name": "-unusedAssets",
                "--ignoreAssets": [
                    "*.so"
                ]
            }
        ],
        "--output": "/xxx"
    }
    

    其中,mm.html 和 mm.json 是微信使用的自定义输出格式,Matrix-ApkChecker 默认提供 html 、json、mm.html 以及 mm.json 四种输出格式。
    要注意的是所有路径都必须是绝对路径,如果是windows系统的话复制文件夹的路径是反斜杠(),会报转义错误,改为正斜杠(/)

    使用配置文件命令如下:

    java -jar matrix-apk-canary-0.4.10.jar --config 配置文件路径
    

    输出这么一串代码就代表执行成功

    Matrix-ApkChecker的功能#

    • 读取manifest的信息

    从AndroidManifest.xml文件中读取apk的全局信息,如packageName、versionCode等

    • 按文件大小排序列出apk中包含的文件

    列出超过一定大小的文件,可按文件后缀过滤,并且按文件大小排序

    • 统计方法数

    统计dex包含的方法数,并支持将输出结果按照类名(class)或者包名(package)来分组

    • 检查是否经过了资源混淆(AndResGuard)

    检查apk是否经过了资源混淆,推荐使用资源混淆来进一步减小apk的大小

    • 搜索不含alpha通道的png文件

    对于不含alpha通道的png文件,可以转成jpg格式来减少文件的大小

    • 检查是否包含多个ABI版本的动态库

    so文件的大小可能会在apk文件大小中占很大的比例,可以考虑在apk中只包含一个ABI版本的动态库

    • 搜索未经压缩的文件类型

    某个文件类型的所有文件都没有经过压缩,可以考虑是否需要压缩

    • 统计apk中包含的R类以及R类中的field count

    编译之后,代码中对资源的引用都会优化成int常量,除了R.styleable之外,其他的R类其实都可以删除

    • 搜索冗余的文件

    对于两个内容完全相同的文件,应该去冗余

    • 检查是否有多个动态库静态链接了STL

    如果有多个动态库都依赖了STL,应该采用动态链接的方式而非多个动态库都去静态链接STL

    • 搜索apk中包含的无用资源

    apk中未经使用到的资源,应该予以删除

    • 搜索apk中包含的无用assets文件

    apk中未经使用的assets文件,应该予以删除

    • 搜索apk中未经裁剪的动态库文件

    动态库经过裁剪之后,文件大小通常会减小很多

    示例分析#

    下面,我们对一个示例apk使用Matrix-ApkChecker进行检查,并根据检查的结果进行针对性的减包优化。
    从Matrix-ApkChecker的输出结果中可以看到示例apk的相关全局信息如下图所示:

    示例 apk 中包含的文件按类型统计如下图所示:

    png文件(不包括 .9.png)未经压缩,可以考虑一定程度的压缩

    存在一些冗余的文件,文件内容相同的文件应该只保留一份

    存在无用资源,包括未使用的系统support包中的资源、第三方资源包中的无用资源以及示例app定义的资源

    存在无用的assets资源,应该删除

    后续#

    了解完Matrix-ApkChecker的基本功能后,后续考虑集成到jenkins中,每次编译产出Apk时运行脚本记录apk的总大小值,对比每个版本的包大小总值,dex、so、图片资源各自占比、是否有重复资源、是否有图片未压缩等,如果能每个版本检查出上述问题并提出优化建议,那么在持续集成中价值就比较大

    参考
    https://github.com/Tencent/matrix/wiki/Matrix-Android-ApkChecker

  • 相关阅读:
    阿里p9技术专家纯手打《程序员“不迷茫”职业路指南》给你指明方向
    【好书推荐】你想要的编码规范都在这里 | 《代码整洁之道》
    vue3 区别于 vue2 的“与众不同”
    Git版本控制管理——合并
    强劲升级,太极2.x你值得拥有!
    flink 自定义序列化对象Sink/Source
    使用VMware搭建OceanStor_eStor存储超详细教程
    奇异码,非奇异码和唯一可译码和即时码的区别
    流量传感器原理介绍
    微信小程序接口请求/form-data/单文件、多文件上传
  • 原文地址:https://www.cnblogs.com/lookingforfreedom/p/15897445.html