简介
Matrix 是微信终端自研和正在使用的一套APM(Application Performance Management)系统。 Matrix-ApkChecker 作为Matrix系统的一部分,是针对android安装包的分析检测工具,根据一系列设定好的规则检测apk是否存在特定的问题,并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪。
具体使用可以查看 Matrix Android ApkChecker 使用文档
功能
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中未经裁剪的动态库文件
动态库经过裁剪之后,文件大小通常会减小很多
使用
下载 Matrix 源码,编译 matrix-apk-canary 部分的源码,该项目是一个 java 项目,以下的使用示例采用 matrix 配置文件的方式进行。相比较命令行而言,配置文件比较简单和实用。
我们可以打开 APKChecker.java
文件,替换 Main 函数的内容为:
public static void main(String... args) { String arr[]= new String[2]; arr[0]="--config"; // 配置文件的目录 arr[1]="/Users/codelang/Desktop/matrix/matrix/matrix-android/matrix-apk-canary/src/main/java/com/tencent/matrix/apk/config.json"; // if (ages.length > 0) { ApkChecker m = new ApkChecker(); m.run(arr); // } else { // System.out.println(INTRODUCT + HELP); // System.exit(0); // } } 复制代码
以上设置的配置文件绝对路径,是我们需要设置给 ApkChecker 进行分析的,当然,如果是使用ApkChecker.jar
来运行的话,则可以使用命令:
java -jar ApkChecker.jar --config 配置文件的绝对路径
我们可以根据官方文档给的配置文件进行设置,配置文件是一个 .json 文件 :
config.json
{ "--apk":"/Users/codelang/mesh/android-test/app/build/outputs/apk/onLine/release/onLine-release-v1.2.0.apk", "--mappingTxt":"/Users/codelang/mesh/android-test/app/build/outputs/mapping/onLine/release/mapping.txt", "--output":"/Users/codelang/Desktop/matrix/matrix/matrix-android/matrix-apk-canary/src/main/java/com/tencent/matrix/apk/", "--format":"mm.html,mm.json", "--formatConfig": [ { "name":"-countMethod", "group": [ { "name":"Android System", "package":"android" }, { "name":"java system", "package":"java" }, { "name":"com.tencent.test.$", "package":"com.tencent.test.$" } ] } ], "options": [ { "name":"-manifest" }, { "name":"-fileSize", "--min":"10", "--order":"desc", "--suffix":"png, jpg, jpeg, gif, arsc" }, { "name":"-countMethod", "--group":"package" }, { "name":"-checkResProguard" }, { "name":"-findNonAlphaPng", "--min":"10" }, { "name":"-checkMultiLibrary" }, { "name":"-uncompressedFile", "--suffix":"png, jpg, jpeg, gif, arsc" }, { "name":"-countR" }, { "name":"-duplicatedFile" }, { "name":"-checkMultiSTL", "--toolnm":"/Users/codelang/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-nm" }, { "name":"-unusedResources", "--rTxt":"/Users/codelang/mesh/android-test/app/build/intermediates/symbols/pre/release/R.txt", "--ignoreResources" :["R.raw.*", "R.style.*", "R.attr.*", "R.id.*", "R.string.ignore_*" ] }, { "name":"-unusedAssets", "--ignoreAssets":["*.so" ] }, { "name":"-unstrippedSo", "--toolnm":"/Users/codelang/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-nm" } ] } 复制代码
配置文件有几个地方是需要我们去替换的:
- --apk : 需要分析的 apk 文件的路径
- --mappingTxt :mapping.txt 文件
- --output : 分析后的输出目录
- --formatConfig 下的 name 和 pacakge :替换成自己的包名,分析结果会统计包名下类的方法数量
- --toolnm : 替换成自己 NDK 下对应的文件即可
- --rTx : apk 文件生成时,对应的 R 文件目录
运行 Apkchecker.java
,会在对应设置的 output
目录生成 .json 和 .html 文件
.json 文件看起来会有点麻烦,可以打开 .html 文件进行查看分析结果: