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

你可能感兴趣的:(Android 微信APM工具 Matrix使用)