本文主要是记录笔者接入微信性能监控框架Matrix的过程,以及简单阐述如何分析Matrix输出的监控数据。
lib_thirds_matrix_version=2.0.8
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.2"
classpath ("com.tencent.matrix:matrix-gradle-plugin:${lib_thirds_matrix_version}") { changing = true }
}
}
apply plugin: 'com.tencent.matrix-plugin'
matrix {
trace {
enable = true //if you don't want to use trace canary, set false
baseMethodMapFile = "${project.buildDir}/matrix_output/Debug.methodmap"
blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
}
}
一般我们是在app module下的build.gradle进行依赖,但是笔者比较喜欢按功能划分module,所以新建一个Module: apmlib, 并且在apmlib的build.gradle下进行依赖。
dependencies {
//按需依赖需要的canary
implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: lib_thirds_matrix_version, changing: true
implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: lib_thirds_matrix_version, changing: true
implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: lib_thirds_matrix_version, changing: true
implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-memory-canary", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-resource-canary-android", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-resource-canary-common", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-sqlite-lint-android-sdk", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-battery-canary", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-hooks", version: lib_thirds_matrix_version, changing: true
// implementation group: "com.tencent.matrix", name: "matrix-backtrace", version: lib_thirds_matrix_version, changing: true
......
}
package com.mikel.apmlib;
import android.app.Application;
import com.tencent.matrix.Matrix;
import com.tencent.matrix.iocanary.IOCanaryPlugin;
import com.tencent.matrix.iocanary.config.IOConfig;
import com.tencent.matrix.trace.TracePlugin;
import com.tencent.matrix.trace.config.TraceConfig;
public class MatrixManager {
private static volatile MatrixManager INSTANCE;
private MatrixManager() {
}
public static MatrixManager getInstance() {
if (INSTANCE == null) {
synchronized (MatrixManager.class) {
if (INSTANCE == null) {
INSTANCE = new MatrixManager();
}
}
}
return INSTANCE;
}
public void doOnCreate(Application application, String splashActivity) {
Matrix.Builder builder = new Matrix.Builder(application); // build matrix
builder.pluginListener(new MatrixPluginListener(application)); // add general pluginListener
MatrixDynamicConfigImpl matrixDynamicConfig = new MatrixDynamicConfigImpl(); // dynamic config
boolean fpsEnable = matrixDynamicConfig.isFPSEnable();
boolean traceEnable = matrixDynamicConfig.isTraceEnable();
//Trace plugin
TraceConfig traceConfig = new TraceConfig.Builder()
.dynamicConfig(matrixDynamicConfig)
.enableFPS(fpsEnable)//帧率
.enableEvilMethodTrace(traceEnable)//慢方法
.enableAnrTrace(traceEnable)//anr
.enableStartup(traceEnable)//启动速度
.splashActivities(splashActivity)//首页
//debug模式
.isDebug(true)
//dev环境
.isDevEnv(false)
.build();
TracePlugin tracePlugin = new TracePlugin(traceConfig);
builder.plugin(tracePlugin);
// io plugin
IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(new IOConfig.Builder()
.dynamicConfig(matrixDynamicConfig)
.build());
builder.plugin(ioCanaryPlugin);
//init matrix
Matrix.init(builder.build());
tracePlugin.start();
ioCanaryPlugin.start();
}
}
本文只使用了Matrix的TraceCanary和IOCanary来做Demo, Matrix的功能远不止这些,还有其他的Canary,可以按需接入。
此外,初始化的时候,可以继承Matrix的DefaultPluginListener进行性能监控的数据监听以及实现IDynamicConfig自定义一些性能监控的阈值。
package com.mikel.apmlib;
import android.content.Context;
import com.tencent.matrix.plugin.DefaultPluginListener;
import com.tencent.matrix.report.Issue;
import com.tencent.matrix.util.MatrixLog;
public class MatrixPluginListener extends DefaultPluginListener {
public static final String TAG = "MatrixPluginListener";
public MatrixPluginListener(Context context) {
super(context);
}
@Override
public void onReportIssue(Issue issue) {
super.onReportIssue(issue);
//todo 处理性能监控数据
MatrixLog.e(TAG, issue.toString());
}
}
package com.mikel.apmlib;
import com.tencent.mrs.plugin.IDynamicConfig;
public class MatrixDynamicConfigImpl implements IDynamicConfig {
public MatrixDynamicConfigImpl() {}
public boolean isFPSEnable() { return true;}
public boolean isTraceEnable() { return true; }
public boolean isMatrixEnable() { return true; }
public boolean isDumpHprof() { return false;}
@Override
public String get(String key, String defStr) {
//hook to change default values
return defStr;
}
@Override
public int get(String key, int defInt) {
//hook to change default values
return defInt;
}
@Override
public long get(String key, long defLong) {
//hook to change default values
// if (IDynamicConfig.ExptEnum.clicfg_matrix_trace_evil_method_threshold.name().equals(key)) {
// return 300; // 默认为700
// }
return defLong;
}
@Override
public boolean get(String key, boolean defBool) {
//hook to change default values
return defBool;
}
@Override
public float get(String key, float defFloat) {
//hook to change default values
return defFloat;
}
}
MatrixManager.getInstance().doOnCreate(getApplication(),"com.mikel.projectdemo.MainActivity");
Matrix 对堆栈进行了聚合,解决堆栈数据量大,后台很难聚类的问题,详细原理见:
Matrix Android TraceCanary · Tencent/matrix Wiki · GitHub
根据TraceStack 的 methidId,在项目app-build-outputs-mapping-debug-methodMapping.txt 找到对应方法。
启动速度监控根据Matrix Trace-Canary 的StartupTracer开头注释很容易理解
application_create: 第一个方法调用时 到 四大组件创建时 对应下图applicationCost
first_activity_create: 第一个方法调用时 到 首个Activity.onWindowFocusChange 对应下图firstScreenCost
冷启动:第一个方法调用时 到 MainActivity.onWindowFocusChange 对应下图coldCost
温启动:首个Activity.onCreate 到 首个Activity.onWindowFocusChange 对应下图warmCost
过滤TAG :Trace_FPS 可以得到帧率监控数据
关键字段解析:
scene: 关键页面
dropLevel: 一个采样周期,根据每60帧的丢帧数落入不同区间的次数。
DROPPED_FROZEN 代表采样周期内每60帧丢了42帧以上的次数
DROPPED_HIGH 代表采样周期内每60帧丢了24-42帧的次数
DROPPED_MIDDLE 代表采样周期内每60帧里丢了9-24帧的次数
DROPPED_NONAL 代表采样周期内每60帧里丢了3-9帧的次数
DROPPED_BEST 代表采样周期内每60帧丢了0-3帧的次数
dropSum: 一个采样周期,落入不同区间的累计丢帧数。
DROPPED_FROZEN 代表采样周期内每60帧丢了42帧以上的累计丢帧数
DROPPED_HIGH 代表采样周期内每60帧丢了24-42帧的累计丢帧数
DROPPED_MIDDLE 代表采样周期内每60帧里丢了9-24帧的累计丢帧数
DROPPED_NONAL 代表采样周期内每60帧里丢了3-9帧的累计丢帧数
DROPPED_BEST 代表采样周期内每60帧丢了0-3帧的累计丢帧数
fps: 帧率, 监控指标