Matrix介绍
Matrix由微信团队研发并开源,支持Android/iOS/macOS 三个平台的性能监控功能,但是目前为止只有Android端是最全的。项目地址:Matrix
Matrix-android 当前监控范围包括:应用安装包大小,帧率变化,启动耗时,卡顿,慢方法,SQLite 操作优化,文件读写,内存泄漏等等。
主要有以下几个插件
- APK Checker: 针对 APK 安装包的分析检测工具,根据一系列设定好的规则,检测 APK 是否存在特定的问题,并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪
- Resource Canary: 基于 WeakReference 的特性和 Square Haha 库开发的 Activity 泄漏和 Bitmap 重复创建检测工具
- Trace Canary: 监控界面流畅性、启动耗时、页面切换耗时、慢函数及卡顿等问题
- SQLite Lint: 按官方最佳实践自动化检测 SQLite 语句的使用质量
- IO Canary: 检测文件 IO 问题,包括:文件 IO 监控和 Closeable Leak 监控
集成步骤
1.在根目录的gradle.properties中配置要依赖的Matrix版本号,注意,目前为止最新版本是0.5.2
MATRIX_VERSION=0.5.2
注意:如果使用0.5.1,会出现新版本0.5.1集成以后,一启动就crash
2.在根目录的build.gradle中添加Matrix依赖
classpath("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
因为changing = true,表示会自动检查更新。一般项目中没必要设置,所以可以简化成如下代码:
classpath "com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}"
3.在app/build.gradle文件中添加Matrix各模块的依赖
dependencies {
implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-resource-canary-android", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-resource-canary-common", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-sqlite-lint-android-sdk", version: MATRIX_VERSION, changing: true
}
apply plugin: 'com.tencent.matrix-plugin'
matrix {
trace {
enable = true
baseMethodMapFile = "${project.projectDir}/matrixTrace/methodMapping.txt"
blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
}
}
因为changing的问题,可以简化成如下:
dependencies {
implementation "com.tencent.matrix:matrix-android-lib:${MATRIX_VERSION}"
implementation "com.tencent.matrix:matrix-android-commons:${MATRIX_VERSION}"
implementation "com.tencent.matrix:matrix-trace-canary:${MATRIX_VERSION}"
implementation "com.tencent.matrix:matrix-resource-canary-android:${MATRIX_VERSION}"
implementation "com.tencent.matrix:matrix-resource-canary-common:${MATRIX_VERSION}"
implementation "com.tencent.matrix:matrix-io-canary:${MATRIX_VERSION}"
implementation "com.tencent.matrix:matrix-sqlite-lint-android-sdk:${MATRIX_VERSION}"
}
apply plugin: 'com.tencent.matrix-plugin'
matrix {
trace {
enable = true
baseMethodMapFile = "${project.projectDir}/matrixTrace/methodMapping.txt"
blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
}
}
注意:apply plugin必须要写在app的build.gradle,否则会提示Matrix Plugin, Android Application plugin required。
enable:如果不需要启用matrix的trace canary,则可以设为false
baseMethodMapFile:trace canary对于慢函数的分析,需要通过method_mapping文件解析堆栈,mapping文件在上传安装包的时候需要一起上传
4.实现PluginListener,负责处理Matrix收集的数据
public class TestPluginListener extends DefaultPluginListener {
public static final String TAG = "TestPluginListener";
public SoftReference<Context> softReference;
public TestPluginListener(Context context) {
super(context);
softReference = new SoftReference<>(context);
}
@Override
public void onReportIssue(Issue issue) {
super.onReportIssue(issue);
MatrixLog.e(TAG, issue.toString());
IssuesMap.put(IssueFilter.getCurrentFilter(), issue);
jumpToIssueActivity();
}
public void jumpToIssueActivity() {
Context context = softReference.get();
Intent intent = new Intent(context, IssuesListActivity.class);
if (context instanceof Application) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
}
注意:1.官方demo是弹出新的activity来显示日志。如果有额外需求,比如记录到文件,均在此类中处理。
注意:2.此处可能需要额外的文件,可以从官方demo中获取。可能用到的文件有IssuesMap、IssueFilter、ParseIssueUtil、IssuesListActivity 以及activity需要的xml文件。
5.实现动态配置接口,可修改Matrix内部参数
可以完全复制DynamicConfigImplDemo
注意:可能会缺少MatrixEnum文件
6.在Application中初始化
//matrix
MatrixDynamicConfig dynamicConfig = new MatrixDynamicConfig();
boolean fpsEnable = dynamicConfig.isFPSEnable();
boolean traceEnable = dynamicConfig.isTraceEnable();
Matrix.Builder builder = new Matrix.Builder(this);
builder.patchListener(new MatrixPluginListener(this));
//trace
TraceConfig traceConfig = new TraceConfig.Builder()
.dynamicConfig(dynamicConfig)
//按照自己需求开启以下监控任务
.enableFPS(fpsEnable)
.enableEvilMethodTrace(traceEnable)
.enableAnrTrace(traceEnable)
.enableStartup(traceEnable)
//一定要写,改成自己项目中的splash页面即可,不然会奔溃
.splashActivities("sample.tencent.matrix.SplashActivity;")
//debug模式
.isDebug(true)
//dev环境
.isDevEnv(false)
.build();
TracePlugin tracePlugin = new TracePlugin(traceConfig);
builder.plugin(tracePlugin);
//resource
ResourceConfig resourceConfig = new ResourceConfig.Builder()
.dynamicConfig(dynamicConfig)
//true获取hprof文件,否则没法分析哪里内存泄露了
.setDumpHprof(true)
//只有官方demo中才会为true
.setDetectDebuger(false)
.build();
ResourcePlugin resourcePlugin = new ResourcePlugin(resourceConfig);
builder.plugin(resourcePlugin);
// 当activity destroy之后,自动断开从引用的view到gc root之间的路径
ResourcePlugin.activityLeakFixer(this);
//io
IOConfig ioConfig = new IOConfig.Builder()
.dynamicConfig(dynamicConfig)
.build();
IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(ioConfig);
builder.plugin(ioCanaryPlugin);
//sqlite
SQLiteLintConfig config = initSQLiteLintConfig();
SQLiteLintPlugin sqLiteLintPlugin = new SQLiteLintPlugin(config);
builder.plugin(sqLiteLintPlugin);
Matrix.init(builder.build());
tracePlugin.start();
ioCanaryPlugin.start();
resourcePlugin.start();
sqLiteLintPlugin.start();
注意1:ResourcePlugin.activityLeakFixer(this);可能会和swipeRefreshLayout冲突issue#68
注意2:可以根据自己需求,决定在release/debug版本开启哪些监控插件。
数据分析
APK Checker
主要功能,很多功能其实和lint工具差不多
1.读取manifest的信息
2.按文件大小排序列出apk中包含的文件
3.统计方法数
4.检查是否经过了资源混淆(AndResGuard)
5.搜索不含alpha通道的png文件
6.检查是否包含多个ABI版本的动态库
7.搜索未经压缩的文件类型
8.统计apk中包含的R类以及R类中的field count
9.搜索冗余的文件
10.检查是否有多个动态库静态链接了STL
11.搜索apk中包含的无用资源
12.搜索apk中包含的无用assets文件
13.搜索apk中未经裁剪的动态库文件
使用步骤
1.下载jar
2.修改配置文件
{
"--apk":"/Users/williamjin/SampleApplication/app/build/outputs/apk/release/AndResGuard_app-release-unsigned/app-release-unsigned_unsigned.apk",
"--mappingTxt":"/Users/williamjin/SampleApplication/app/build/outputs/mapping/release/mapping.txt",
"--output":"/Users/williamjin/SampleApplication/app/build/outputs/apk-checker-result",
"--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/williamjin/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm"
},
{
"name":"-unusedResources",
"--rTxt":"/Users/williamjin/SampleApplication/app/build/intermediates/symbols/release/R.txt",
"--ignoreResources"
:["R.raw.*",
"R.style.*",
"R.attr.*",
"R.id.*",
"R.string.ignore_*"
]
},
{
"name":"-unusedAssets",
"--ignoreAssets":["*.so" ]
},
{
"name":"-unstrippedSo",
"--toolnm":"/Users/williamjin/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm"
}
]
}
注意1:其中“--apk”,“--mappingTxt”,“--output”,“--toolnm”,“--rTxt”需要修改为自己的路径
注意2:配置文件中的任务,可以按照自己的需求修改。
3.终端运行命令
java -jar matrix-apk-canary-0.5.1.jar --config matrix-apk-checker.json
4.分析结果
Resource Canary--可以替换LeakCanary
使用步骤:plugin.start()之后无需任何操作
分析结果
1.在初始化的时候,设置.setDumpHprof(true)
2.在app的cache/matrix_resource目录中找到zip文件
3.解压即可得到hprof文件
4.转成mat支持的标准hprof文件,使用sdk-->platform-tools-->hprof-conv工具文件,命令如下
hprof-conv -z 源文件路径 目标文件路径
5.使用mat打开hprof文件,并且分析文件 mat下载地址
IO Canary
使用步骤:plugin.start()之后无需任何操作
分析结果:看下文
SQLite Lint
使用步骤:plugin.start()之后无需任何操作
分析结果:看下文
Trace Canary
使用步骤:plugin.start()之后无需任何操作
分析结果:看下文
数据分析
总结
文章可能有我理解不对的地方,如果发现,我会及时改正。
目前Matrix只在微信中大规模应用,而微信用的第三方以及开发环境可能和我们正式的项目稍有不同,所以暂时可能会有些没解决的问题。希望Matrix尽快修复这些问题,并且优化的越来越好吧。