Matrix-android 當(dāng)前監(jiān)控范圍包括:應(yīng)用安裝包大小,幀率變化,啟動(dòng)耗時(shí),卡頓,慢方法,SQLite 操作優(yōu)化,文件讀寫(xiě),內(nèi)存泄漏等等。
- APK Checker: 針對(duì) APK 安裝包的分析檢測(cè)工具,根據(jù)一系列設(shè)定好的規(guī)則,檢測(cè) APK 是否存在特定的問(wèn)題,并輸出較為詳細(xì)的檢測(cè)結(jié)果報(bào)告,用于分析排查問(wèn)題以及版本追蹤
- Resource Canary: 基于 WeakReference 的特性和 Square Haha 庫(kù)開(kāi)發(fā)的 Activity 泄漏和 Bitmap 重復(fù)創(chuàng)建檢測(cè)工具
- Trace Canary: 監(jiān)控ANR、界面流暢性、啟動(dòng)耗時(shí)、頁(yè)面切換耗時(shí)、慢函數(shù)及卡頓等問(wèn)題
- SQLite Lint: 按官方最佳實(shí)踐自動(dòng)化檢測(cè) SQLite 語(yǔ)句的使用質(zhì)量
- IO Canary: 檢測(cè)文件 IO 問(wèn)題,包括:文件 IO 監(jiān)控和 Closeable Leak 監(jiān)控
- Battery Canary: 監(jiān)控 App 活躍線程(待機(jī)狀態(tài) & 前臺(tái) Loop 監(jiān)控)、ASM 調(diào)用 (WakeLock/Alarm/Gps/Wifi/Bluetooth 等傳感器)、 后臺(tái)流量 (Wifi/移動(dòng)網(wǎng)絡(luò))等 Battery Historian 統(tǒng)計(jì) App 耗電的數(shù)據(jù)
特性
與常規(guī)的 APM 工具相比,Matrix 擁有以下特點(diǎn):
APK Checker
- 具有更好的可用性:JAR 包方式提供,更方便應(yīng)用到持續(xù)集成系統(tǒng)中,從而追蹤和對(duì)比每個(gè) APK 版本之間的變化
- 更多的檢查分析功能:除具備 APKAnalyzer 的功能外,還支持統(tǒng)計(jì) APK 中包含的 R 類、檢查是否有多個(gè)動(dòng)態(tài)庫(kù)靜態(tài)鏈接了 STL 、搜索 APK 中包含的無(wú)用資源,以及支持自定義檢查規(guī)則等
- 輸出的檢查結(jié)果更加詳實(shí):支持可視化的 HTML 格式,便于分析處理的 JSON ,自定義輸出等等
Resource Canary
- 分離了檢測(cè)和分析部分,便于在不打斷自動(dòng)化測(cè)試的前提下持續(xù)輸出分析后的檢測(cè)結(jié)果
- 對(duì)檢測(cè)部分生成的 Hprof 文件進(jìn)行了裁剪,移除了大部分無(wú)用數(shù)據(jù),降低了傳輸 Hprof 文件的開(kāi)銷
- 增加了重復(fù) Bitmap 對(duì)象檢測(cè),方便通過(guò)減少冗余 Bitmap 數(shù)量,降低內(nèi)存消耗
Trace Canary
- 編譯期動(dòng)態(tài)修改字節(jié)碼, 高性能記錄執(zhí)行耗時(shí)與調(diào)用堆棧
- 準(zhǔn)確的定位到發(fā)生卡頓的函數(shù),提供執(zhí)行堆棧、執(zhí)行耗時(shí)、執(zhí)行次數(shù)等信息,幫助快速解決卡頓問(wèn)題
- 自動(dòng)涵蓋卡頓、啟動(dòng)耗時(shí)、頁(yè)面切換、慢函數(shù)檢測(cè)等多個(gè)流暢性指標(biāo)
- 準(zhǔn)確監(jiān)控ANR,并且能夠高兼容性和穩(wěn)定性地保存系統(tǒng)產(chǎn)生的ANR Trace文件
SQLite Lint
- 接入簡(jiǎn)單,代碼無(wú)侵入
- 數(shù)據(jù)量無(wú)關(guān),開(kāi)發(fā)、測(cè)試階段即可發(fā)現(xiàn)SQLite性能隱患
- 檢測(cè)算法基于最佳實(shí)踐,高標(biāo)準(zhǔn)把控SQLite質(zhì)量*
- 底層是 C++ 實(shí)現(xiàn),支持多平臺(tái)擴(kuò)展
IO Canary
- 接入簡(jiǎn)單,代碼無(wú)侵入
- 性能、泄漏全面監(jiān)控,對(duì) IO 質(zhì)量心中有數(shù)
- 兼容到 Android P
Battery Canary
- 接入簡(jiǎn)單,開(kāi)箱即用
- 預(yù)留 Base 類和 Utility 工具以便擴(kuò)展監(jiān)控特性
Memory Hook
- 一個(gè)檢測(cè) Android native 內(nèi)存泄漏的工具
- 無(wú)侵入,基于 PLT-hook(iqiyi/xHook),無(wú)需重編 native 庫(kù)
- 高性能,基于 Wechat-Backtrace 進(jìn)行快速 unwind 堆棧,支持 aarch64 和 armeabi-v7a 架構(gòu)
Pthread Hook
- 一個(gè)檢測(cè) Android Java 和 native 線程泄漏及縮減 native 線程??臻g的工具
- 無(wú)侵入,基于 PLT-hook(iqiyi/xHook),無(wú)需重編 native 庫(kù)
- 通過(guò)對(duì) native 線程的默認(rèn)棧大小進(jìn)行減半降低線程帶來(lái)的虛擬內(nèi)存開(kāi)銷,在 32 位環(huán)境下可緩解虛擬內(nèi)存不足導(dǎo)致的崩潰問(wèn)題
WVPreAllocHook
- 一個(gè)用于安全釋放 WebView 預(yù)分配內(nèi)存以在不加載 WebView 時(shí)節(jié)省虛擬內(nèi)存的工具,在 32 位環(huán)境下可緩解虛擬內(nèi)存不足導(dǎo)致的崩潰問(wèn)題
- 無(wú)侵入,基于 PLT-hook(iqiyi/xHook),無(wú)需重編 native 庫(kù)
- 使用該工具后 WebView 仍可正常工作
Backtrace Component
- 基于 DWARF 以及 ARM 異常處理數(shù)據(jù)進(jìn)行簡(jiǎn)化并生成全新的 quicken unwind tables 數(shù)據(jù),用于實(shí)現(xiàn)可快速回溯 native 調(diào)用棧的 backtrace 組件?;厮菟俣燃s是 libunwindstack 的 15x ~ 30x 左右。
使用方法
由于 JCenter 服務(wù)將于 2022 年 2 月 1 日下線,我們已將 Matrix 新版本(>= 0.8.0) maven repo 發(fā)布至 MavenCentral。
- 在你項(xiàng)目根目錄下的 gradle.properties 中配置要依賴的 Matrix 版本號(hào),如:
MATRIX_VERSION=2.0.1
- 在你項(xiàng)目根目錄下的 build.gradle 文件添加 Matrix 依賴,如:
dependencies {
classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
}
- 接著,在 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
implementation group: "com.tencent.matrix", name: "matrix-battery-canary", version: MATRIX_VERSION, changing: true
implementation group: "com.tencent.matrix", name: "matrix-hooks", version: 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"
}
}
目前 Matrix gradle plugin 支持 Android Gradle Plugin 3.5.0/4.0.0/4.1.0。
- 實(shí)現(xiàn) PluginListener,接收 Matrix 處理后的數(shù)據(jù), 如:
public class TestPluginListener extends DefaultPluginListener {
public static final String TAG = "Matrix.TestPluginListener";
public TestPluginListener(Context context) {
super(context);
}
@Override
public void onReportIssue(Issue issue) {
super.onReportIssue(issue);
MatrixLog.e(TAG, issue.toString());
//add your code to process data
}
}
- 實(shí)現(xiàn)動(dòng)態(tài)配置接口, 可修改 Matrix 內(nèi)部參數(shù). 在 sample-android 中 我們有個(gè)簡(jiǎn)單的動(dòng)態(tài)接口實(shí)例DynamicConfigImplDemo.java, 其中參數(shù)對(duì)應(yīng)的 key 位于文件 MatrixEnum中, 摘抄部分示例如下:
public class DynamicConfigImplDemo implements IDynamicConfig {
public DynamicConfigImplDemo() {}
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
}
@Override
public int get(String key, int defInt) {
//hook to change default values
}
@Override
public long get(String key, long defLong) {
//hook to change default values
}
@Override
public boolean get(String key, boolean defBool) {
//hook to change default values
}
@Override
public float get(String key, float defFloat) {
//hook to change default values
}
}
- 選擇程序啟動(dòng)的位置對(duì) Matrix 進(jìn)行初始化,如在 Application 的繼承類中, Init 核心邏輯如下:
Matrix.Builder builder = new Matrix.Builder(application); // build matrix
builder.pluginListener(new TestPluginListener(this)); // add general pluginListener
DynamicConfigImplDemo dynamicConfig = new DynamicConfigImplDemo(); // dynamic config
// init plugin
IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(new IOConfig.Builder()
.dynamicConfig(dynamicConfig)
.build());
//add to matrix
builder.plugin(ioCanaryPlugin);
//init matrix
Matrix.init(builder.build());
// start plugin
ioCanaryPlugin.start();
至此,Matrix就已成功集成到你的項(xiàng)目中,并且開(kāi)始收集和分析性能相關(guān)異常數(shù)據(jù),如仍有疑問(wèn),請(qǐng)查看 示例.
PS:
- 從 v0.9.0 開(kāi)始,Matrix for Android 遷移到了 AndroidX. 你可能需要添加 'android.useAndroidX=true' 標(biāo)志到 gradle.properties 文件里。
- Matrix 分析后的輸出字段的含義請(qǐng)查看 Matrix 輸出內(nèi)容的含義解析
Battery Canary Usage
相關(guān)初始化代碼如下:
BatteryMonitorConfig config = new BatteryMonitorConfig.Builder()
.enable(JiffiesMonitorFeature.class)
.enableStatPidProc(true)
.greyJiffiesTime(30 * 1000L)
.setCallback(new BatteryMonitorCallback.BatteryPrinter())
.build();
BatteryMonitorPlugin plugin = new BatteryMonitorPlugin(config);
具體使用方式,請(qǐng)參考單元測(cè)試?yán)锵嚓P(guān)用例的代碼: com.tencent.matrix.batterycanary.ApisTest 或 sample.tencent.matrix.battery.BatteryCanaryInitHelper.
Backtrace Component Usage
如何初始化 backtrace 組件:
WeChatBacktrace.instance().configure(getApplicationContext()).commit();
初始化后其他 Matrix 組件就可以使用 Quicken Backtrace 進(jìn)行回溯。更多參數(shù)的配置請(qǐng)查看 WeChatBacktrace.Configuration 的接口注釋。
APK Checker
APK Check 以獨(dú)立的 jar 包提供 (matrix-apk-canary-2.0.1.jar),你可以運(yùn)行:
java -jar matrix-apk-canary-2.0.1.jar
查看 Usages 來(lái)使用它。
Usages:
--config CONFIG-FILE-PATH
or
[--input INPUT-DIR-PATH] [--apk APK-FILE-PATH] [--unzip APK-UNZIP-PATH] [--mappingTxt MAPPING-FILE-PATH] [--resMappingTxt RESGUARD-MAPPING-FILE-PATH] [--output OUTPUT-PATH] [--format OUTPUT-FORMAT] [--formatJar OUTPUT-FORMAT-JAR] [--formatConfig OUTPUT-FORMAT-CONFIG (json-array format)] [Options]
Options:
-manifest
Read package info from the AndroidManifest.xml.
-fileSize [--min DOWN-LIMIT-SIZE (KB)] [--order ORDER-BY ('asc'|'desc')] [--suffix FILTER-SUFFIX-LIST (split by ',')]
Show files whose size exceed limit size in order.
-countMethod [--group GROUP-BY ('class'|'package')]
Count methods in dex file, output results group by class name or package name.
-checkResProguard
Check if the resguard was applied.
-findNonAlphaPng [--min DOWN-LIMIT-SIZE (KB)]
Find out the non-alpha png-format files whose size exceed limit size in desc order.
-checkMultiLibrary
Check if there are more than one library dir in the 'lib'.
-uncompressedFile [--suffix FILTER-SUFFIX-LIST (split by ',')]
Show uncompressed file types.
-countR
Count the R class.
-duplicatedFile
Find out the duplicated resource files in desc order.
-checkMultiSTL --toolnm TOOL-NM-PATH
Check if there are more than one shared library statically linked the STL.
-unusedResources --rTxt R-TXT-FILE-PATH [--ignoreResources IGNORE-RESOURCES-LIST (split by ',')]
Find out the unused resources.
-unusedAssets [--ignoreAssets IGNORE-ASSETS-LIST (split by ',')]
Find out the unused assets file.
-unstrippedSo --toolnm TOOL-NM-PATH
Find out the unstripped shared library file.
由于篇幅影響,此次不再贅述,我們?cè)?Matrix-APKChecker 中進(jìn)行了詳細(xì)說(shuō)明。