Android 微信APM工具 Matrix使用

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尽快修复这些问题,并且优化的越来越好吧。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容