在集成Matrix的时候,商业化使用的时候,即使是腾讯官方的,也要很多问题和bug,或者需要修改自己需要的需求,所以要自己看懂源码修改,和发布自己的插件
-
1).官方版本存在Bug且停止更新(2022年后无维护)
-
2). Matrix和KOOM和LeakCanary,3者同时集成,用到的Shark冲突问题
源码整体的结构:

1.Matrix存在的问题
1.1 不能找到stack, 一直是空的,key, (比较严重的问题)
比如像这种情况:
json
{
"machine": "BEST",
"cpu_app": 1.6837534748442526e-5,
"mem": 17180917760,
"mem_free": 13995736,
"detail": "NORMAL",
"cost": 401,
"scene": "default",
"stack": "",
"stackKey": "",
"tag": "GW_Trace_EvilMethod",
"process": "com.gwm.cloudsmartvoice",
"time": 1741239663891
}
显示的是"tag": "GW_Trace_EvilMethod"!
所以可以知道是插桩出了问题! 继续看源码,找到解决方案:
手动在EvilMethodTracer,慢方法触发器中添加,
AppMethodBeat.i(AppMethodBeat.METHOD_ID_DISPATCH);
AppMethodBeat.o(AppMethodBeat.METHOD_ID_DISPATCH);
ini
@Override
public void onDispatchBegin(String log) {
// MatrixLog.w(TAG,"onDispatchBegin");
indexRecord = AppMethodBeat.getInstance().maskIndex("EvilMethodTracer#dispatchBegin");
AppMethodBeat.i(AppMethodBeat.METHOD_ID_DISPATCH);
}
```
@Override
public void onDispatchEnd(String log, long beginNs, long endNs) {
// MatrixLog.w(TAG,"onDispatchEnd"+Thread.currentThread().getName());
AppMethodBeat.o(AppMethodBeat.METHOD_ID_DISPATCH);
long dispatchCost = (endNs - beginNs) / Constants.TIME_MILLIS_TO_NANO;
try {
if (dispatchCost >= evilThresholdMs) {
long[] data = AppMethodBeat.getInstance().copyData(indexRecord);
String scene = AppActiveMatrixDelegate.INSTANCE.getVisibleScene();
MatrixHandlerThread.getDefaultHandler().post(new AnalyseTask(isForeground(), scene, data, dispatchCost, endNs));
}
} finally {
indexRecord.release();
}
}
1.2 如果是抽象类可能不会找到, 经常会到handler
如何阻止某个类被混淆? 设置白名单! 和黑名单
如下是报告的结果:
swift
tag[GW_Trace_EvilMethod]type[0];key[null];content[{"machine":"BEST","cpu_app":1.6837534748442526E-5,"mem":17180917760,"mem_free":13995736,"detail":"NORMAL","cost":401,"scene":"default","stack":"0,1048574,1,401\n1,7459,1,0\n2,6490,1,0\n3,5712,1,0\n1,7447,1,0\n2,10554,1,0\n3,2415,1,0\n4,2423,1,0\n3,2792,1,0\n2,2428,1,0\n1,12667,2,0\n1,403,1,0\n1,462,1,0\n2,265,1,0\n3,215,1,0\n4,12669,1,0\n3,260,1,0\n1,7459,1,0\n2,6490,1,0\n3,5712,1,0\n1,7447,1,0\n2,10554,1,0\n3,2415,1,0\n4,2423,1,0\n3,2792,1,0\n2,2428,1,0\n1,7580,1,0\n1,7588,1,397\n1,12667,1,0\n1,7459,1,0\n","stackKey":"7588|","tag":"GW_Trace_EvilMethod","process":"com.gwm.cloudsmartvoice","time":1741239663891}]
查找映射方法,会指向最终的方法,和dispatchMessage ,找不到调用链关系! 1048574,1,android.os.Handler dispatchMessage (Landroid.os.Message;)V
自己有问题的方法:
kotlin
abstract public class AsrStateUiMange
查看源码:插桩的源码,不支持抽象方法的插桩
-
定位文件 :
matrix-gradle-plugin/src/main/java/com/tencent/matrix/trace/transformer/MatrixTraceTransformer.java
及其相关的ClassVisitor
/MethodVisitor
。 -
修改逻辑 : 找到跳过
ACC_ABSTRACT
和ACC_INTERFACE
的判断条件。目标是跳过接口和抽象的声明方法,但对抽象类中的具体实现方法进行插桩。 -
示例代码修改: // 原始代码可能类似这样,会跳过所有抽象类和接口 if ((access & Opcodes.ACC_ABSTRACT) != 0 || (access & Opcodes.ACC_INTERFACE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); }
scss// 修改为:仅跳过抽象方法和接口中的方法 boolean isAbstractMethod = (access & Opcodes.ACC_ABSTRACT) != 0; boolean isInterfaceClass = (access & Opcodes.ACC_INTERFACE) != 0; // 注意:这个是类的access,可能需要从ClassVisitor获取 if (isAbstractMethod || isInterfaceClass) { // 如果是抽象方法或接口类中的任何方法,跳过插桩 return super.visitMethod(access, name, desc, signature, exceptions); } // 否则(即抽象类中的具体方法),进行正常插
使用 Matrix 提供的 trace.py
脚本解析数字栈。
1.3 官方Matrix的demo中的悬浮窗帧率,总是不会实时更新帧率的UI
FrameTracer里面的tryCallBackAndReset(),方法, 里面的reset,导致根本采集不到
ini
void tryCallBackAndReset() {
if (count > 20) {
dropCount /= count;
this.refreshRate /= count;
totalDuration /= count;
for (int i = 0; i < durations.length; i++) {
durations[i] /= count;
}
listener.onFrameMetricsAvailable(lastScene, durations, dropLevel, dropSum,
dropCount, this.refreshRate, Constants.TIME_SECOND_TO_NANO / totalDuration);
}
reset(); // 问题
}
修改后:
ini
void tryCallBackAndReset() {
if (count > 20) {
dropCount /= count;
this.refreshRate /= count;
totalDuration /= count;
for (int i = 0; i < durations.length; i++) {
durations[i] /= count;
}
listener.onFrameMetricsAvailable(lastScene, durations, dropLevel, dropSum,
dropCount, this.refreshRate, Constants.TIME_SECOND_TO_NANO / totalDuration);
reset(); // 修改后
}
}
1.4 Matrix 无法监控悬浮窗的FPS,帧率,需要自己解决
原因就是Actvity对象和Window对象! 帧率监控用的原理是:
ini
Window.OnFrameMetricsAvailableListener onFrameMetricsAvailableListener = new Window.OnFrameMetricsAvailableListener() {
private float cachedRefreshRate = defaultRefreshRate;
private float cachedThreshold = dropFrameListenerThreshold / 60f * cachedRefreshRate;
private int lastModeId = -1;
private int lastThreshold = -1;
private WindowManager.LayoutParams attributes = null;
private void updateRefreshRate(Window window) {
if (attributes == null) {
attributes = window.getAttributes();
}
if (attributes.preferredDisplayModeId != lastModeId || lastThreshold != dropFrameListenerThreshold) {
lastModeId = attributes.preferredDisplayModeId;
lastThreshold = dropFrameListenerThreshold;
cachedRefreshRate = getRefreshRate(window);
cachedThreshold = dropFrameListenerThreshold / 60f * cachedRefreshRate;
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics, int dropCountSinceLastInvocation) {
if (isForeground()) {
// skip not available metrics.
for (int i = FrameDuration.UNKNOWN_DELAY_DURATION.ordinal(); i <= FrameDuration.TOTAL_DURATION.ordinal(); i++) {
long v = frameMetrics.getMetric(FrameDuration.indices[i]);
if (v < 0 || v >= HALF_MAX) {
// some devices will produce outliers, especially the Honor series, eg: NTH-AN00, ANY-AN00, etc.
return;
}
}
FrameMetrics frameMetricsCopy = new FrameMetrics(frameMetrics);
updateRefreshRate(window);
long totalDuration = frameMetricsCopy.getMetric(FrameMetrics.TOTAL_DURATION);
float frameIntervalNanos = Constants.TIME_SECOND_TO_NANO / cachedRefreshRate;
float droppedFrames = Math.max(0f, (totalDuration - frameIntervalNanos) / frameIntervalNanos);
droppedSum += droppedFrames;
if (dropFrameListener != null && droppedFrames >= cachedThreshold) {
dropFrameListener.onFrameMetricsAvailable(ProcessUILifecycleOwner.INSTANCE.getVisibleScene(), frameMetricsCopy, droppedFrames, cachedRefreshRate);
}
synchronized (listeners) {
for (IFrameListener observer : listeners) {
observer.onFrameMetricsAvailable(ProcessUILifecycleOwner.INSTANCE.getVisibleScene(), frameMetricsCopy, droppedFrames, cachedRefreshRate);
}
}
}
}
};
activity.getWindow().addOnFrameMetricsAvailableListener(onFrameMetricsAvailableListener, MatrixHandlerThread.getDefaultHandler());
要通过window对象添加addOnFrameMetricsAvailableListener(), 悬浮窗不能拿到Activity,一般都是services,所以要拿到window对象,就能解决问题!
问题就变成了,悬浮窗如何获取window对象? 或者可以看Toast的源码,自己写一个类似Toast的悬浮窗 或者:Choreographer
2. gradle的整体项目的运行流程:原理
2.1 源码架构
源码的目录:matrix-android
css
matrix-android/
├── matrix-gradle-plugin # Gradle插件模块
├── matrix-trace-canary # 卡顿/ANR监控
├── matrix-memory-canary # 内存泄漏检测
├── matrix-io-canary # 文件IO监控
├── gradle/
│ ├── android-publish.gradle # 发布配置
│ └── check.gradle # 代码检查
└── settings.gradle # 模块聚合配置
Matrix架构
A[Matrix Core] --> B[APM插件]
A --> C[资源监控插件]
A --> D[内存优化插件]
B --> B1[TraceCanary]
B --> B2[IOCanary]
C --> C1[Thread Monitor]
D --> D1[MemoryCanary]
E[Gradle Plugin] -->|动态注入| A
F[本地Maven] -->|发布| E
F -->|依赖| G[Demo App]
搞懂了这个,才知道怎么修改和发布 这个项目这么多module,怎么看起始的运行gradle?
要看发布的插件pluin的module
matrix-gradle-plugin
根目录的setting gradle配置开始,然后有ndk的编译
Arguments.gradle 所在的目录位置
php
apply from: "$rootDir/gradle/Arguments.gradle"
// Gradle plugin
include ':matrix-gradle-plugin'
}
调用关系:
调用matrix-gradle-plugin.gradlew的里面,然后调用了gradle/XXX.grade文件
matrix-gradle-plugin: 在task中执行发布的脚本,就可以发布了
gradle文件中有有很多的gradle文件!

1).android-publish 每个module都用到了
2).java-publish.gradle matrix-gradle-plugin中用到了
3).build_library.gradle ------> android-publish-private.gradle ------>check.gradle
发布的时候: 是不是一个模块一个模块单独发布的,还是一起发布,那么就有依赖关系,全部打包到不同的模块
目前看是单独发布的,没有依赖关系!
bash
Searched in the following locations:
- file:/C:/Users/GW00355722/.m2/repository/com/tencent/matrix/matrix-arscutil/2.2.2/matrix-arscutil-2.2.2.pom

build_library.gradle
(公共基础配置)
这是所有 Android Library Module 的基础配置脚本 。它被应用在每个模块的 build.gradle
中,作用是确保所有模块的构建配置统一。
通常包含:
- 通用 Android 配置 :
compileSdkVersion
,buildToolsVersion
,defaultConfig
(minSdk, targetSdk, versionCode, versionName)等。 - 通用依赖库 :统一引入所有模块都可能用到的依赖,如
androidx.appcompat
。 - 应用其他脚本 :通过
apply from: "$rootDir/gradle/android-publish.gradle"
和apply from: "$rootDir/gradle/check.gradle"
来引入发布和检查能力。
android-publish.gradle
(Android模块发布配置)
这个脚本被 Android Library Module (如 matrix-trace-canary
, matrix-memory-canary
)使用。它基于 maven-publish
和 signing
插件,配置如何将 AAR 包发布到 Maven 仓库
3.自定义matrix插件发布步骤:(重点)
腾讯最终发布的插件 "com.tencent.matrix:matrix-memory-canary:2.1.0"
3.1 需要你的需要改的代码
3.2.修改自己要发布的版本和名字
找到: gradle.properties 发布的配置:版本信息
Internal (for wechat), External (for public repo), 我们选择External 修改:
VERSION_NAME_PREFIX=3.1.0 // 之前源码是2.1.0
VERSION_NAME_SUFFIX=
PUBLISH_CHANNEL=External // 源码是Internal
android.useAndroidX=true // 保持不
3.3.studio 出现右边的任务发布
找到 :matrix-commons
模块。找到每个模块对应的task

右边的task没见了,提示android task list not buildt
设置一下gradle配置
- 在Android Studio的Gradle面板中找到 :matrix-gradle-plugin > Tasks > publishing > publishToMavenLocal
3.4 一个插件一个插件的发布到本地, 因为有多个插件模块
4.1点击publishing里面的任务: 发布到本地电脑用publishToMavenLocal,发布私服: PublishComponentPublicationToMavenResitory
发布是没有顺序的,不会因依赖导致发布错误,但是集成到demo中是有依赖关系的
问题: Could not find com.tencent.matrix:matrix-commons:2.2.2
原因 : 您只发布了 matrix-gradle-plugin
,但它所依赖的其他模块(如 matrix-commons
, matrix-arscutil
)在本地仓库中不存在。
解决 : 必须将所有依赖的模块都发布到本地仓库 。您需要按顺序执行以下模块的 publishToMavenLocal
:
matrix-android-lib
-> matrix-commons
-> matrix-arscutil
-> matrix-gradle-plugin
-> matrix-trace-canary
-> ...
或者更简单的方法:在根目录下执行 ./gradlew publishToMavenLocal
,Gradle的Task依赖机制会自动按顺序发布所有模块。
3.5 是否发布成功! 发布成功后的位置:
当使用 mavenLocal() 发布时,生成的文件会被发布到本地 Maven 仓库。
在大多数系统中,默认的本地 Maven 仓库位置是用户目录下的 .m2/repository 目录。
例如,在 Windows 系统中,通常是 C:\Users<用户名>.m2\repository;

总结:
- 修改版本号 : 在
gradle.properties
中修改VERSION_NAME_PREFIX
(如改为3.1.0
) 和PUBLISH_CHANNEL=External
。 - 独立发布模块 : Matrix的各个模块(
-plugin
,-canary
) 是相互独立的,可以分别发布到Maven仓库。它们之间的依赖关系是通过Maven坐标在集成时解决的。 - 执行发布任务 : 在Android Studio的Gradle面板中,对每个需要发布的模块,执行
publishing > publishToMavenLocal
(发布到本地)或publish
(发布到远程仓库)。 - 验证发布 : 发布成功后,在
~/.m2/repository/com/tencent/matrix/
目录下找到对应版本号的文件夹,检查.pom
,.jar
,.aar
文件是否齐全。
4.验证和使用自己发布的插件在官方的demo中替代
4.1 项目的gradle中设置添加依赖:
arduino
classpath "com.tencent.matrix:matrix-gradle-plugin:3.2.0"
4.2 配置依赖从本地加载
scss
mavenLocal()
4.3 单个项目的根gradle设置
arduino
implementation "com.tencent.matrix:matrix-trace-canary:3.2.0" // 是否需要在根目录
整体如下:
csharp
// 项目根build.gradle
buildscript {
repositories {
mavenLocal() // 优先从本地加载
}
dependencies {
classpath "com.tencent.matrix:matrix-gradle-plugin:3.1.0" # 改为自定义版本
}
}
csharp
// App模块build.gradle
dependencies {
implementation "com.tencent.matrix:matrix-trace-canary:3.1.0" # 同步版本
}
如果用的是官方的demo,只需要改一个数字就可以了:
ini
buildscript {
ext {
minSdkVersion = 19
targetSdkVersion = 29
compileSdkVersion = 29
buildToolsVersion = '29.0.2'
javaVersion = JavaVersion.VERSION_1_8
MATRIX_VERSION = "3.1.0" // 修改这个
GROUP = 'com.tencent.matrix'
VERSION_NAME = "${MATRIX_VERSION}"
github的仓库源码,解决了编译的版本, 包含正确的gradle版本
总结:
-
项目根
build.gradle
:scssbuildscript { repositories { mavenLocal() // 必须添加,优先从本地仓库寻找 google() mavenCentral() } dependencies { classpath "com.android.tools.build:gradle:4.2.1" // 注意Gradle插件版本兼容性 classpath "com.tencent.matrix:matrix-gradle-plugin:3.1.0" // 你的自定义版本 } }
-
App模块
build.gradle
:arduinoapply plugin: 'com.tencent.matrix-plugin' // 应用插件 dependencies { implementation "com.tencent.matrix:matrix-android-lib:3.1.0" implementation "com.tencent.matrix:matrix-trace-canary:3.1.0" implementation "com.tencent.matrix:matrix-memory-canary:3.1.0" // ... 其他所需组件 }
5.发布的解决常见问题
- 注意事项:确保NDK版本匹配,依赖顺序一致。
报错:Failed to install the following SDK components:
ndk;23.1.7779620 NDK (Side by side) 23.1.7779620
Install the missing components using the SDK manager in Android Studio.
- NDK缺失报错:通过Android Studio的SDK Manager安装指定版本NDK(如23.1.7779620)。
- 依赖顺序:插件可独立发布(无编译依赖),但集成时需按功能顺序引入(如trace-canary依赖matrix-core)。
需要用这个编译
bash
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.7.1-all.zip
A problem occurred configuring root project 'biaozhunProject _aiTextView'.
> Could not resolve all artifacts for configuration ':classpath'.
> Could not find com.tencent.matrix:matrix-commons:2.2.2.
Searched in the following locations:
- file:/C:/Users/GW00355722/.m2/repository/com/tencent/matrix/matrix-commons/2.2.2/matrix-commons-2.2.2.pom
- https://jitpack.io/com/tencent/matrix/matrix-commons/2.2.2/matrix-commons-2.2.2.pom
- https://dl.google.com/dl/android/maven2/com/tencent/matrix/matrix-commons/2.2.2/matrix-commons-2.2.2.pom
- https://repo.maven.apache.org/maven2/com/tencent/matrix/matrix-commons/2.2.2/matrix-commons-2.2.2.pom
Required by:
project : > com.tencent.matrix:matrix-gradle-plugin:2.2.2
> Could not find com.tencent.matrix:matrix-arscutil:2.2.2.
Searched in the following locations:
- file:/C:/Users/GW00355722/.m2/repository/com/tencent/matrix/matrix-arscutil/2.2.2/matrix-arscutil-2.2.2.pom
- https://jitpack.io/com/tencent/matrix/matrix-arscutil/2.2.2/matrix-arscutil-2.2.2.pom
- https://dl.google.com/dl/android/maven2/com/tencent/matrix/matrix-arscutil/2.2.2/matrix-arscutil-2.2.2.pom
- https://repo.maven.apache.org/maven2/com/tencent/matrix/matrix-arscutil/2.2.2/matrix-arscutil-2.2.2.pom
Required by:
project : > com.tencent.matrix:matrix-gradle-plugin:2.2.2
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
找不到
typescript
buildscript {
// ext.shadow_version = '2.2.1'
repositories {
mavenLocal()
maven { url 'https://jitpack.io' }
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
classpath "com.tencent.matrix:matrix-gradle-plugin:2.2.2"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
下载ndk: 21. 3669的版本
使用的时候: 是用1个,还是用3个,发现用多个也是没有问题的!
csharp
implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: "2.2.2", changing: true
implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: "2.2.2", changing: true
implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: "2.2.2", changing: true
自带的saple,用的是7.5 7.4.2
kotlin用的是
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20'
版本只需要修改一个这个值就可以了!
MATRIX_VERSION = "2.2.2"
进去会奔溃,没有进行配置
ini
// Configure resource canary.
ResourcePlugin resourcePlugin = configureResourcePlugin(dynamicConfig);
builder.plugin(resourcePlugin);
有很多版本的问题,jdk。recyclewView的版本,现在选择的是11jdk
跟 下面这个没有关系!
ruby
// compileOptions {
// sourceCompatibility JavaVersion.VERSION_1_8
// targetCompatibility JavaVersion.VERSION_1_8
// }
./gradlew :app:dependencies
F:\2025_important_demo\20250419_important\app\build\intermediates\merged_java_res\debug\out.jar: 另一个程序正在使用此文件,进程无法访问
./gradlew --stop