Giter VIP home page Giter VIP logo

matrix's Introduction

Matrix-icon license PRs Welcome WeChat Approved CircleCI

(中文版本请参看这里)

Matrix for iOS/macOS 中文版
Matrix for android 中文版
Matrix for iOS/macOS
Matrix for android

Matrix is an APM (Application Performance Manage) used in Wechat to monitor, locate and analyse performance problems. It is a plugin style, non-invasive solution and is currently available on iOS, macOS and Android.

The monitoring scope of the current tool includes: crash, lag, and memory, which includes the following three plugins:

  • WCCrashBlockMonitorPlugin: Based on KSCrash framework, it features cutting-edge lag stack capture capabilities with crash capture.

  • WCMemoryStatPlugin: A memory monitoring tool that captures memory allocation and the callstack of an application's memory event.

  • WCFPSMonitorPlugin: A fps monitoring tool that captures main thread's callstack while user scrolling.

Features

WCCrashBlockMonitorPlugin

  • Easy integration, no code intrusion.
  • Determine whether the app is stuck by checking the running status of the Runloop, and support both the iOS and macOS platform.
  • Add time-consuming stack fetching, attaching the most time-consuming main thread stack to the thread snapshot log.

WCMemoryStatPlugin

  • Live recording every object's creating and the corresponding callstack of its creation, and report it when the application out-of-memory is detected.

Getting Started

Install

  • Install with static framework
    1. Get source code of Matrix;
    2. Open terminal, execute make in the matrix/matrix-iOS directory to compile and generate static library. After compiling, the iOS platform library is in the matrix/matrix-iOS/build_ios directory, and the macOS platform library is in the matrix/matrix-iOS/build_macos directory.
    3. Link with static framework in the project:
    • iOS : Use Matrix.framework under the matrix/matrix-iOS/build_ios path, link Matrix.framework to the project as a static library;
    • macOS : Use Matrix.framework under the matrix/matrix-iOS/build_macos path, link Matrix.framework to the project as a static library.
    1. Add #import <Matrix/Matrix.h>, then you can use the performance probe tool of WeChat.

Start the plugins

In the following places:

  • Program main function;
  • application:didFinishLaunchingWithOptions: of AppDelegate;
  • Or other places running as earlier as possible after application launching.

Add a code similar to the following to start the plugin:

#import <Matrix/Matrix.h>
  
Matrix *matrix = [Matrix sharedInstance];
MatrixBuilder *curBuilder = [[MatrixBuilder alloc] init];
curBuilder.pluginListener = self; // get the related event of plugin via the callback of the pluginListener
    
WCCrashBlockMonitorPlugin *crashBlockPlugin = [[WCCrashBlockMonitorPlugin alloc] init];    
[curBuilder addPlugin:crashBlockPlugin]; // add lag and crash monitor.
    
WCMemoryStatPlugin *memoryStatPlugin = [[WCMemoryStatPlugin alloc] init];
[curBuilder addPlugin:memoryStatPlugin]; // add memory monitor.

WCFPSMonitorPlugin *fpsMonitorPlugin = [[WCFPSMonitorPlugin alloc] init];
[curBuilder addPlugin:fpsMonitorPlugin]; // add fps monitor.
    
[matrix addMatrixBuilder:curBuilder];
    
[crashBlockPlugin start]; // start the lag and crash monitor.
[memoryStatPlugin start]; // start memory monitor
[fpsMonitorPlugin start]; // start fps monitor

Receive callbacks to obtain monitoring data

Set pluginListener of the MatrixBuilder object, implement the MatrixPluginListenerDelegate

// set delegate

MatrixBuilder *curBuilder = [[MatrixBuilder alloc] init];
curBuilder.pluginListener = <object conforms to MatrixPluginListenerDelegate>; 

// MatrixPluginListenerDelegate

- (void)onInit:(id<MatrixPluginProtocol>)plugin;
- (void)onStart:(id<MatrixPluginProtocol>)plugin;
- (void)onStop:(id<MatrixPluginProtocol>)plugin;
- (void)onDestroy:(id<MatrixPluginProtocol>)plugin;
- (void)onReportIssue:(MatrixIssue *)issue;

Each plugin added to MatrixBuilder will call back the corresponding event via pluginListener.

Important: Get the monitoring data of the Matrix via onReportIssue:, the data format info reference to Matrix for iOS/macOS Data Format Description

Tutorials

At this point, Matrix has been integrated into the app and is beginning to collect crash, lag, and memory data. If you still have questions, check out the example: samples/sample-iOS/MatrixDemo.

Plugins

  • APK Checker:

    Analyse the APK package, give suggestions of reducing the APK's size; Compare two APK and find out the most significant increment on size

  • Resource Canary:

    Detect the activity leak and bitmap duplication basing on WeakReference and Square Haha

  • Trace Canary:

    FPS Monitor, Startup Performance, ANR, UI-Block / Slow Method Detection

  • SQLite Lint:

    Evaluate the quality of SQLite statement automatically by using SQLite official tools

  • IO Canary:

    Detect the file IO issues, including performance of file IO and closeable leak

  • Battery Canary:

    App thread activities monitor (Background watch & foreground loop watch), Sonsor usage monitor (WakeLock/Alarm/Gps/Wifi/Bluetooth), Background network activities (Wifi/Mobile) monitor.

  • MemGuard

    Detect heap memory overlap, use-after-free and double free issues.

Features

APK Checker

  • Easy-to-use. Matrix provides a JAR tool, which is more convenient to apply to your integration systems.
  • More features. In addition to APK Analyzer, Matrix find out the R redundancies, the dynamic libraries statically linked STL, unused resources, and supports custom checking rules.
  • Visual Outputs. supports HTML and JSON outputs.

Resource Canary

  • Separated detection and analysis. Make possible to use in automated test and in release versions (monitor only).
  • Pruned Hprof. Remove the useless data in hprof and easier to upload.
  • Detection of duplicate bitmap.

Trace Canary

  • High performance. Dynamically modify bytecode at compile time, record function cost and call stack with little performance loss.
  • Accurate call stack of ui-block. Provide informations such as call stack, function cost, execution times to solve the problem of ui-block quickly.
  • Non-hack. High compatibility to Android versions.
  • More features. Automatically covers multiple fluency indicators such as ui-block, startup time, activity switching, slow function detection.
  • High-accuracy ANR detector. Detect ANRs accurately and give ANR trace file with high compatibility and high stability.

SQLite Lint

  • Easy-to-use. Non-invasive.
  • High applicability. Regardless of the amount of data, you can discover SQLite performance problems during development and testing.
  • High standards. Detection algorithms based on best practices, make SQLite statements to the highest quality.
  • May support multi-platform. Implementing in C++ makes it possible to support multi-platform.

IO Canary

  • Easy-to-use. Non-invasive.
  • More feature. Including performance of file IO and closeable leak.
  • Compatible with Android P.

Battery Canary

  • Easy-to-use. Use out of box (unit tests as example).
  • More feature. Flexible extending with base and utils APIs.

Memory Hook

  • A native memory leak detection tool for Android.
  • Non-invasive. It is based on PLT-hook(iqiyi/xHook), so we do NOT need to recompile the native libraries.
  • High performance. we use WeChat-Backtrace for fast unwinding which supports both aarch64 and armeabi-v7a architectures.

Pthread Hook

  • A Java and native thread leak detection and native thread stack space trimming tool for Android.
  • Non-invasive. It is based on PLT-hook(iqiyi/xHook), so we do NOT need to recompile the native libraries.
  • It saves virtual memory overhead by trimming default stack size of native thread in half, which can reduce crashes caused by virtual memory insufficient under 32bit environment.

WVPreAllocHook

  • A tool for saving virtual memory overhead caused by WebView preloading when WebView is not actually used. It's useful for reducing crashes caused by virtual memory insufficient under 32bit environment.
  • Non-invasive. It is based on PLT-hook(iqiyi/xHook), so we do NOT need to recompile the native libraries.
  • WebView still works after using this tool.

MemGuard

  • A tool base on GWP-Asan to detect heap memory issues.

  • Non-invasive. It is based on PLT-hook(iqiyi/xHook), so we do NOT need to recompile the native libraries.

  • It's able to apply on specific libraries that needs to be detected by RegEx.

  • It detects heap memory accessing overlap, use-after-free and double free issues.

Backtrace Component

  • A fast native backtrace component designed by Matrix based on quicken unwind tables that are generated and simplified from DWARF and ARM exception handling informations. It is about 15x ~ 30x faster than libunwindstack.

Getting Started

The JCenter repository will stop service on February 1, 2022. So we uploaded Matrix(since 0.8.0) to the MavenCentral repository.

  1. Configure MATRIX_VERSION in gradle.properties.
  MATRIX_VERSION=2.1.0
  1. Add matrix-gradle-plugin in your build.gradle:
  dependencies {
      classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
  }
 
  1. Add dependencies to your app/build.gradle.
  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
    implementation group: "com.tencent.matrix", name: "matrix-backtrace", 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"
    }
  }
  1. Implement PluginListener to receive data processed by Matrix.
  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
    }
}

Matrix gradle plugin could work with Android Gradle Plugin 3.5.0/4.0.0/4.1.0 currently.

  1. Implement DynamicConfig to change parameters of Matrix.
  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
    }
}
  1. Init Matrix in the onCreate of your application.
  Matrix.Builder builder = new Matrix.Builder(application); // build matrix
  builder.patchListener(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();

For more Matrix configurations, look at the sample.

Note:

  1. Since Matrix for Android has migrated to AndroidX since v0.9.0. You may need to add 'android.useAndroidX=true' flag to gradle.properties
  2. You can get more about Matrix output at the wiki The output of Matrix;

Battery Canary Usage

Init BatteryCanary as the following codes:

BatteryMonitorConfig config = new BatteryMonitorConfig.Builder()
        .enable(JiffiesMonitorFeature.class)
        .enableStatPidProc(true)
        .greyJiffiesTime(30 * 1000L)
        .setCallback(new BatteryMonitorCallback.BatteryPrinter())
        .build();

BatteryMonitorPlugin plugin = new BatteryMonitorPlugin(config);

For detail usage, please reference showcase tests at com.tencent.matrix.batterycanary.ApisTest or sample.tencent.matrix.battery.BatteryCanaryInitHelper.

Backtrace Component Usage

How to init backtrace component:

WeChatBacktrace.instance().configure(getApplicationContext()).commit();

Then other components in Matrix could use Quikcen Backtrace to unwind stacktrace. See more configuration comments in 'WeChatBacktrace.Configuration'.

APK Checker Usage

APK Checker can run independently in Jar (matrix-apk-canary-2.1.0.jar) mode, usage:

java -jar matrix-apk-canary-2.1.0.jar
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.

Learn more about Matrix-APKChecker

Support

Any problem?

  1. Learn more from Sample
  2. Source Code
  3. Wiki & FAQ
  4. Contact us for help

Contributing

If you are interested in contributing, check out the CONTRIBUTING.md, also join our Tencent OpenSource Plan.

License

Matrix is under the BSD license. See the LICENSE file for details


Matrix-icon licensePRs Welcome WeChat Approved

Matrix 是一款微信研发并日常使用的应用性能接入框架,支持iOS, macOS和Android。 Matrix 通过接入各种性能监控方案,对性能监控项的异常数据进行采集和分析,输出相应的问题分析、定位与优化建议,从而帮助开发者开发出更高质量的应用。

Matrix-iOS 当前工具监控范围包括:崩溃、卡顿和内存,包含以下三款插件:

  • WCCrashBlockMonitorPlugin: 基于 KSCrash 框架开发,具有业界领先的卡顿堆栈捕获能力,同时兼备崩溃捕获能力

  • WCMemoryStatPlugin: 一款性能极致的内存监控工具,能够全面捕获应用 OOM 时的内存分配以及调用堆栈情况

  • WCFPSMonitorPlugin: 一款 FPS 监控工具,当用户滑动界面时,记录主线程调用栈

特性

WCCrashBlockMonitorPlugin

  • 接入简单,代码无侵入
  • 通过检查 Runloop 运行状态判断应用是否卡顿,同时支持 iOS/macOS 平台
  • 增加耗时堆栈提取,卡顿线程快照日志中附加最近时间最耗时的主线程堆栈

WCMemoryStatPlugin

  • 在应用运行期间获取对象存活以及相应的堆栈信息,在检测到应用 OOM 时进行上报

使用方法

安装

  • 通过静态库安装
    1. 获取 Matrix 源码;
    2. 打开命令行,在 matrix/matrix-iOS 代码目录下执行 make 进行编译生成静态库;编译完成后,iOS 平台的库在 matrix/matrix-iOS/build_ios 目录下,macOS 平台的库在 matrix/matrix-iOS/build_macos 目录下;
    3. 工程引入静态库:
    • iOS 平台:使用 matrix/matrix-iOS/build_ios 路径下的 Matrix.framework,将 Matrix.framework 以静态库的方式引入工程;
    • macOS 平台:使用 matrix/matrix-iOS/build_macos 路径下的 Matrix.framework,将 Matrix.framework 以静态库的方式引入工程。
    1. 添加头文件 #import <Matrix/Matrix.h>,就可以接入微信的性能探针工具了!

启动监控

在以下地方:

  • 程序 main 函数入口;
  • AppDelegate 中的 application:didFinishLaunchingWithOptions:
  • 或者其他应用启动比较早的时间点。

添加类似如下代码,启动插件:

#import <Matrix/Matrix.h>
  
Matrix *matrix = [Matrix sharedInstance];
MatrixBuilder *curBuilder = [[MatrixBuilder alloc] init];
curBuilder.pluginListener = self; // pluginListener 回调 plugin 的相关事件
    
WCCrashBlockMonitorPlugin *crashBlockPlugin = [[WCCrashBlockMonitorPlugin alloc] init];    
[curBuilder addPlugin:crashBlockPlugin]; // 添加卡顿和崩溃监控
    
WCMemoryStatPlugin *memoryStatPlugin = [[WCMemoryStatPlugin alloc] init];
[curBuilder addPlugin:memoryStatPlugin]; // 添加内存监控功能

WCFPSMonitorPlugin *fpsMonitorPlugin = [[WCFPSMonitorPlugin alloc] init];
[curBuilder addPlugin:fpsMonitorPlugin]; // 添加 fps 监控功能
    
[matrix addMatrixBuilder:curBuilder];
    
[crashBlockPlugin start]; // 开启卡顿和崩溃监控
[memoryStatPlugin start]; // 开启内存监控
[fpsMonitorPlugin start]; // 开启 fps 监控

接收回调获得监控数据

设置 MatrixBuilder 对象中的 pluginListener,实现 MatrixPluginListenerDelegate。

// 设置 delegate

MatrixBuilder *curBuilder = [[MatrixBuilder alloc] init];
curBuilder.pluginListener = <一个遵循 MatrixPluginListenerDelegate 的对象>; 

// MatrixPluginListenerDelegate

- (void)onInit:(id<MatrixPluginProtocol>)plugin;
- (void)onStart:(id<MatrixPluginProtocol>)plugin;
- (void)onStop:(id<MatrixPluginProtocol>)plugin;
- (void)onDestroy:(id<MatrixPluginProtocol>)plugin;
- (void)onReportIssue:(MatrixIssue *)issue;

各个添加到 MatrixBuilder 的 plugin 会将对应的事件通过 pluginListener 回调。

重要:通过 onReportIssue: 获得 Matrix 处理后的数据,监控数据格式详见:Matrix for iOS/macOS 数据格式说明

Demo

至此,Matrix 已经集成到应用中并且开始收集崩溃、卡顿和爆内存数据,如仍有疑问,请查看示例:samples/sample-iOS/MatrixDemo

Matrix-android 当前监控范围包括:应用安装包大小,帧率变化,启动耗时,卡顿,慢方法,SQLite 操作优化,文件读写,内存泄漏等等。

  • APK Checker: 针对 APK 安装包的分析检测工具,根据一系列设定好的规则,检测 APK 是否存在特定的问题,并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪

  • Resource Canary: 基于 WeakReference 的特性和 Square Haha 库开发的 Activity 泄漏和 Bitmap 重复创建检测工具

  • Trace Canary: 监控ANR、界面流畅性、启动耗时、页面切换耗时、慢函数及卡顿等问题

  • SQLite Lint: 按官方最佳实践自动化检测 SQLite 语句的使用质量

  • IO Canary: 检测文件 IO 问题,包括:文件 IO 监控和 Closeable Leak 监控

  • Battery Canary: 监控 App 活跃线程(待机状态 & 前台 Loop 监控)、ASM 调用 (WakeLock/Alarm/Gps/Wifi/Bluetooth 等传感器)、 后台流量 (Wifi/移动网络)等 Battery Historian 统计 App 耗电的数据

  • MemGuard

    检测堆内存访问越界、使用释放后的内存、重复释放等问题

特性

与常规的 APM 工具相比,Matrix 拥有以下特点:

APK Checker

  • 具有更好的可用性:JAR 包方式提供,更方便应用到持续集成系统中,从而追踪和对比每个 APK 版本之间的变化
  • 更多的检查分析功能:除具备 APKAnalyzer 的功能外,还支持统计 APK 中包含的 R 类、检查是否有多个动态库静态链接了 STL 、搜索 APK 中包含的无用资源,以及支持自定义检查规则等
  • 输出的检查结果更加详实:支持可视化的 HTML 格式,便于分析处理的 JSON ,自定义输出等等

Resource Canary

  • 分离了检测和分析部分,便于在不打断自动化测试的前提下持续输出分析后的检测结果
  • 对检测部分生成的 Hprof 文件进行了裁剪,移除了大部分无用数据,降低了传输 Hprof 文件的开销
  • 增加了重复 Bitmap 对象检测,方便通过减少冗余 Bitmap 数量,降低内存消耗

Trace Canary

  • 编译期动态修改字节码, 高性能记录执行耗时与调用堆栈
  • 准确的定位到发生卡顿的函数,提供执行堆栈、执行耗时、执行次数等信息,帮助快速解决卡顿问题
  • 自动涵盖卡顿、启动耗时、页面切换、慢函数检测等多个流畅性指标
  • 准确监控ANR,并且能够高兼容性和稳定性地保存系统产生的ANR Trace文件

SQLite Lint

  • 接入简单,代码无侵入
  • 数据量无关,开发、测试阶段即可发现SQLite性能隐患
  • 检测算法基于最佳实践,高标准把控SQLite质量*
  • 底层是 C++ 实现,支持多平台扩展

IO Canary

  • 接入简单,代码无侵入
  • 性能、泄漏全面监控,对 IO 质量心中有数
  • 兼容到 Android P

Battery Canary

  • 接入简单,开箱即用
  • 预留 Base 类和 Utility 工具以便扩展监控特性

Memory Hook

  • 一个检测 Android native 内存泄漏的工具
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 高性能,基于 Wechat-Backtrace 进行快速 unwind 堆栈,支持 aarch64 和 armeabi-v7a 架构

Pthread Hook

  • 一个检测 Android Java 和 native 线程泄漏及缩减 native 线程栈空间的工具
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 通过对 native 线程的默认栈大小进行减半降低线程带来的虚拟内存开销,在 32 位环境下可缓解虚拟内存不足导致的崩溃问题

WVPreAllocHook

  • 一个用于安全释放 WebView 预分配内存以在不加载 WebView 时节省虚拟内存的工具,在 32 位环境下可缓解虚拟内存不足导致的崩溃问题
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 使用该工具后 WebView 仍可正常工作

MemGuard

  • 一个基于 GWP-Asan 修改的堆内存问题检测工具
  • 无侵入,基于 PLT-hook(iqiyi/xHook),无需重编 native 库
  • 可根据正则表达式指定被检测的目标库
  • 可检测堆内存访问越界、使用释放后的内存和双重释放等问题

Backtrace Component

  • 基于 DWARF 以及 ARM 异常处理数据进行简化并生成全新的 quicken unwind tables 数据,用于实现可快速回溯 native 调用栈的 backtrace 组件。回溯速度约是 libunwindstack 的 15x ~ 30x 左右。

使用方法

由于 JCenter 服务将于 2022 年 2 月 1 日下线,我们已将 Matrix 新版本(>= 0.8.0) maven repo 发布至 MavenCentral。

  1. 在你项目根目录下的 gradle.properties 中配置要依赖的 Matrix 版本号,如:
  MATRIX_VERSION=2.1.0
  1. 在你项目根目录下的 build.gradle 文件添加 Matrix 依赖,如:
  dependencies {
      classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
  }
  1. 接着,在 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。

  1. 实现 PluginListener,接收 Matrix 处理后的数据, 如:
  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
    }
}
  1. 实现动态配置接口, 可修改 Matrix 内部参数. 在 sample-android 中 我们有个简单的动态接口实例DynamicConfigImplDemo.java, 其中参数对应的 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
    }
}
  1. 选择程序启动的位置对 Matrix 进行初始化,如在 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就已成功集成到你的项目中,并且开始收集和分析性能相关异常数据,如仍有疑问,请查看 示例.

PS:

  1. 从 v0.9.0 开始,Matrix for Android 迁移到了 AndroidX. 你可能需要添加 'android.useAndroidX=true' 标志到 gradle.properties 文件里。
  2. Matrix 分析后的输出字段的含义请查看 Matrix 输出内容的含义解析

Battery Canary Usage

相关初始化代码如下:

BatteryMonitorConfig config = new BatteryMonitorConfig.Builder()
        .enable(JiffiesMonitorFeature.class)
        .enableStatPidProc(true)
        .greyJiffiesTime(30 * 1000L)
        .setCallback(new BatteryMonitorCallback.BatteryPrinter())
        .build();

BatteryMonitorPlugin plugin = new BatteryMonitorPlugin(config);

具体使用方式,请参考单元测试里相关用例的代码: com.tencent.matrix.batterycanary.ApisTestsample.tencent.matrix.battery.BatteryCanaryInitHelper.

Backtrace Component Usage

如何初始化 backtrace 组件:

WeChatBacktrace.instance().configure(getApplicationContext()).commit();

初始化后其他 Matrix 组件就可以使用 Quicken Backtrace 进行回溯。更多参数的配置请查看 WeChatBacktrace.Configuration 的接口注释。

APK Checker

APK Check 以独立的 jar 包提供 (matrix-apk-canary-2.1.0.jar),你可以运行:

java -jar matrix-apk-canary-2.1.0.jar

查看 Usages 来使用它。

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.

由于篇幅影响,此次不再赘述,我们在 Matrix-APKChecker 中进行了详细说明。

Support

还有其他问题?

  1. 查看示例
  2. 阅读源码
  3. 阅读 WikiFAQ
  4. 联系我们。

参与贡献

关于 Matrix 分支管理、issue 以及 pr 规范,请阅读 Matrix Contributing Guide

腾讯开源激励计划 鼓励开发者的参与和贡献,期待你的加入。

License

Matrix is under the BSD license. See the LICENSE file for details

信息公示

  • SDK名称:Matrix
  • 版本号:2.1.0
  • 开发者:深圳市腾讯计算机系统有限公司
  • 主要功能:Matrix是微信研发并日常使用的应用性能监控工具,支持iOS、macOS和Android。Matrix通过接入闪退、卡顿、耗电、内存等方面的监控方案,对性能监控项的异常数据进行采集和分析,输出相应的问题分析、定位与优化建议,从而帮助开发者开发出更高质量的应用。
  • Matrix SDK使用说明
  • Matrix SDK个人信息保护规则

matrix's People

Contributors

0xflotus avatar alanllwang avatar aoramd avatar astrozhou avatar bilue404 avatar changelcai avatar chenzhu33 avatar chzhij5 avatar cntrump avatar dfenglei avatar gengjiawen avatar ghostflying avatar gryamy avatar hamberluo avatar hehonghui avatar jasonross avatar jqctop1 avatar kaedea avatar kealdishx avatar kirozhao avatar knight-zxw avatar lingol avatar lolobug avatar supersg avatar tendahuang avatar txfelixzhou avatar tys282000 avatar wizzxu avatar xjshi avatar yves0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

matrix's Issues

集成调用会报错

调用ioCanaryPlugin.start(); 报错

错误详情: couldn't find "libio-canary.so

代码疑惑

EvilMethodTracer类的onCreate方法和onDestory方法的实现就统计而言的作用是什么?通过查看代码发现,只是初始化和销毁一些对象,而不去调用初始化的方法,依然可以统计到比如enter、anr和evilmethod的性能信息,那这两个方法的作用是什么呢?

源码编译bug

编译 matrix-android 显示:

To suppress this warning, remove "buildToolsVersion '27.0.3'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':matrix-io-canary'.
> ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 1s
ABIs [armeabi] are not supported for platform. Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64].
12:21:38: Task execution finished 'assemble'.

image
导入 Android Studio 一致显示: Index paused due to batch update

Matrix.init error : NullPointerException

异常类型:app运行时异常/编译异常
初始化异常
手机型号:如:Nexus 5(如是编译异常,则可以不填)
模拟器 x*6
手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)
android P
matrix版本:如:0.4.5
0.4.5
gradle版本:如:2.10
3.1.0
问题描述:如:在android O 出现系统不兼容 

堆栈/日志:
1. 如是编译异常,请在执行gradle命令时,加上--stacktrace;
2. 日志我们需要过滤"Matrix."关键字;

 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Iterator java.util.HashSet.iterator()' on a null object reference
        at com.tencent.matrix.Matrix.<init>(Matrix.java:46)
        at com.tencent.matrix.Matrix.<init>(Matrix.java:32)
        at com.tencent.matrix.Matrix$Builder.build(Matrix.java:163)

我的初始化代码:

 private void initMatrix(){
        Matrix.Builder builder = new Matrix.Builder(this); // build matrix
        builder.patchListener(new TestPluginListener(this)); // add general pluginListener


        //init matrix
        Matrix.init(builder.build());

    }

config配置选项放进json 命令行运行报错

java -jar APKChecker.jar --config ./config.json
[INFO][Matrix.ApkJob]format list [html]
Unknown option: null
直接用命令行配置正常输出,但是把配置写进配置文件(config.json)和jar包同一文件路径,报错如上,是使用方法不正确吗

Not a JSON Object: null

Issue /提问须知

在提交 issue 之前,我们应该先查询是否已经有相关的 issue 以及常见问题。提交 issue 时,我们需要写明 issue 的原因,以及编译或运行过程的日志。issue 需要以下面的格式:

异常类型:app 运行时异常/编译异常

手机型号:如: Nexus 5(如是编译异常,则可以不填)

手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)

matrix版本:如: 0.4.7

gradle版本:如: 3.0.0

问题描述:如:在 android O 出现系统不兼容 

堆栈/日志:
1. 如是编译异常,请在执行 gradle 命令时,加上 --stacktrace;
2. 日志我们需要过滤" Matrix. "关键字;

提问题时若使用不能用/没效果/有问题/报错此类模糊表达,但又没给出任何代码截图报错的,将绝对不会有任何反馈。这种 issue 也是一律直接关闭的,大家可以参阅提问的智慧

Matrix 是一个开源项目,希望大家遇到问题时要学会先思考,看看 Sample 与 Matrix 的源码,更鼓励大家给我们提 pr .

与第三方so库不兼容

异常类型:app 运行时异常

手机系统版本:5.1.1

matrix版本:0.4.7

gradle版本:3.1.2

问题描述:工程中引用了第三放的库,运行时报找不到so文件,是这个第三方库没有arm的so?

异常信息:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.xxxx.xxx-1/base.apk"],nativeLibraryDirectories=[/data/app/com.xxxx.xxx/lib/arm, /vendor/lib, /system/lib]]] couldn't find "xxx.so"

jar包如何使用

java -jar ApkChecker.jar --apk debug.apk -manifest
我把jar包0.4.7下载下来之后 将他和apk放在同一个文件夹中,输入如上命令,返回null
看终端的doc貌似可以写在一个json文件里,是否可以给出正确的使用方式

APK Checker 运行异常,提示无法删除 classes2.dex

异常类型:APK Checker 运行异常

运行平台:win10 cmd java version 1.8.0_121

问题描述:APK Checker 运行时报错

堆栈/日志:
[INFO][Matrix.ApkJob]format list [mm.html, mm.json]
[DEBUG][Matrix.UnZipTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2.2.1-11-1221094719.apk
[DEBUG][Matrix.UnZipTask]outputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[DEBUG][Matrix.UnZipTask]D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip exists, delete it.
[DEBUG][Matrix.ManifestAnalyzeTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[DEBUG][Matrix.ShowFileSizeTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[DEBUG][Matrix.MethodCountTask]input path:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[DEBUG][Matrix.ResProguardCheckTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[DEBUG][Matrix.MultiLibCheckTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[INFO][Matrix.MultiSTLCheckTask]toolnm pah is D:\Android\sdk\ndk-bundle\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-nm.exe
[DEBUG][Matrix.MultiSTLCheckTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[DEBUG][Matrix.UnusedAssetsTask]ignore assets 1
[INFO][Matrix.UnStrippedSoCheckTask]toolnm pah is D:\Android\sdk\ndk-bundle\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-nm.exe
[DEBUG][Matrix.UnStrippedSoCheckTask]inputPath:D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip
[INFO][Matrix.ResProguardCheckTask]directory anim has a non-proguard name!
[DEBUG][Matrix.MultiSTLCheckTask]lib: libijkplayer.so has stl link
[DEBUG][Matrix.UnusedResourcesTask]ignore resource R.styleable.ActionBar
[DEBUG][Matrix.UnusedResourcesTask]ignore resource R.styleable.ActionBar_background

。(Matrix.UnusedResourcesTask ignore resource)

[DEBUG][Matrix.UnusedResourcesTask]find resource declarations 4302 items.
[DEBUG][Matrix.UnusedResourcesTask]find resource references in classes: 3143 items.
[DEBUG][Matrix.UnusedResourcesTask]find resource references 4194 items.
[DEBUG][Matrix.UnusedResourcesTask]find unused references 363 items
[DEBUG][Matrix.UnusedAssetsTask]find all assets count: 1
[DEBUG][Matrix.UnusedAssetsTask]find reference assets count: 1
[DEBUG][Matrix.UnStrippedSoCheckTask]lib: libijkffmpeg.so is not stripped
[DEBUG][Matrix.UnStrippedSoCheckTask]lib: libijkplayer.so is not stripped
[DEBUG][Matrix.UnStrippedSoCheckTask]lib: libijksdl.so is not stripped
[DEBUG][Matrix.UnStrippedSoCheckTask]lib: libjcore121.so is not stripped
[DEBUG][Matrix.UnStrippedSoCheckTask]lib: librtmp-jni.so is not stripped
[DEBUG][Matrix.ApkJob]parse apk end, try to delete tmp un zip files
[ERROR][Matrix.ApkJob]Task executor execute with error:Unable to delete file: D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip\classes2.dex
java.io.IOException: Unable to delete file: D:\mvmplayerBak\122109\app-1221094719\app-website-2_unzip\classes2.dex
at org.apache.commons.io.FileUtils.forceDelete(FileUtils.java:2400)
at org.apache.commons.io.FileUtils.cleanDirectory(FileUtils.java:1721)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1617)
at com.tencent.matrix.apk.model.job.ApkJob.execute(ApkJob.java:513)
at com.tencent.matrix.apk.model.job.ApkJob.run(ApkJob.java:469)
at com.tencent.matrix.apk.ApkChecker.run(ApkChecker.java:90)
at com.tencent.matrix.apk.ApkChecker.main(ApkChecker.java:80)

代码疑惑咨询

在FrameTracer.java类里面:
public void doFrame(final long lastFrameNanos, final long frameNanos) {
.....................
listener.getHandler().post(new Runnable() {
@OverRide
public void run() {
listener.getHandler().post(new AsyncDoFrameTask(listener,
lastFrameNanos, frameNanos, getScene(), droppedCount));
}
});
}

1.Async异步的实现本质上是通过启动新线程(listener.getHandler()所属的线程,在demo里是HandlerThread("test"))来调用doFrame,AsyncDoFrameTask本身并没有同步或者异步的实现。
2.上面代码里向HandlerThread("test")所在的messagequeue里面抛送了两次runnable,是不是有些冗余,理论上等同于:
public void doFrame(final long lastFrameNanos, final long frameNanos) {
.....................
listener.getHandler().post(new AsyncDoFrameTask(listener,
lastFrameNanos, frameNanos, getScene(), droppedCount));
}
个人的一点疑惑,冒昧提出,如果是自己理解错了还请海涵哈。

Transform除了支持增量,是否可以支持一下并发,缓存

Transform处理class/jar对编译速度的影响还是比较明显的,从Android build gradle插件自带的几个transform看,大部分除了支持增量,还支持并发与缓存。

目前看MatrixTraceTransform只支持了增量,是否可以支持一下并发,缓存

Nothing

Issue/提问须知

在提交issue之前,我们应该先查询是否已经有相关的issue以及常见问题。提交issue时,我们需要写明issue的原因,以及编译或运行过程的日志。issue需要以下面的格式:

异常类型:app运行时异常/编译异常

手机型号:如:Nexus 5(如是编译异常,则可以不填)

手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)

matrix版本:如:0.4.5

gradle版本:如:2.10

问题描述:如:在android O 出现系统不兼容 

堆栈/日志:
1. 如是编译异常,请在执行gradle命令时,加上--stacktrace;
2. 日志我们需要过滤"Matrix."关键字;

提问题时若使用不能用/没效果/有问题/报错此类模糊表达,但又没给出任何代码截图报错的,将绝对不会有任何反馈。这种issue也是一律直接关闭的,大家可以参阅提问的智慧

Matrix是一个开源项目,希望大家遇到问题时要学会先思考,看看Sample与Matrix的源码,更鼓励大家给我们提pr.

com.google.gson.stream.MalformedJsonException: Unterminated object

环境:mac 10.13.6
java 1.8.0_111

我尝试着去分析apk,但是老是提示json的错误,我已经确认我的json文件是没有问题的
日记是
java -jar matrix-apk-canary-0.4.7.jar --config apkcheckconfig.json
com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 304 path $.--formatConfig

config文件添加到附件,github不支持上传json文件,我改成txt格式上传
apkcheckconfig.txt

可以给点意见吗?

Matrix.UnusedResourcesTask---The Resource declarations file 'R.txt' is not legal!

执行apkChecker jar 通过config文件传递参数 发生如下错误

[ERROR][Matrix.ApkJob]Task executor execute with error:Matrix.UnusedResourcesTask---The Resource declarations file 'R.txt' is not legal!
com.tencent.matrix.apk.model.exception.TaskInitException: Matrix.UnusedResourcesTask---The Resource declarations file 'R.txt' is not legal!
at com.tencent.matrix.apk.model.task.UnusedResourcesTask.init(UnusedResourcesTask.java:106)
at com.tencent.matrix.apk.model.job.ApkJob.execute(ApkJob.java:492)
at com.tencent.matrix.apk.model.job.ApkJob.run(ApkJob.java:469)
at com.tencent.matrix.apk.ApkChecker.run(ApkChecker.java:90)
at com.tencent.matrix.apk.ApkChecker.main(ApkChecker.java:80)

ApkChecker countR 能提供一些优化建议么

编译之后,代码中对资源的引用都会优化成int常量,除了R.styleable之外,其他的R类其实都可以删除

没太看懂 R.java文件中除了styleable,其他的都删掉?

ApkChecker 代码健壮性BUG

java.io.IOException: Unable to delete file: E:\Work\recompile.\apks\XXAPK\XXAPK_unzip\lib\arm64-v8a\libxxx.so
at org.apache.commons.io.FileUtils.forceDelete(FileUtils.java:2400)
at org.apache.commons.io.FileUtils.cleanDirectory(FileUtils.java:1721)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1617)
unzip目录是工具自己创建

Failed to apply plugin [id 'com.tencent.matrix-plugin']

matrix版本:如: 0.4.7
gradle版本:4.10.2
android studio版本:3.2.1
android插件版本:如: 3.2.1

问题描述:如:插件不兼容

堆栈/日志:
`

  • Exception is:
    org.gradle.api.GradleScriptException: A problem occurred evaluating project ':app'.
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:206)
    at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:211)
    at org.gradle.configuration.BuildOperationScriptPlugin$1$1.run(BuildOperationScriptPlugin.java:69)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:66)
    at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:63)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:48)
    at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:63)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:41)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
    at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:105)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:687)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:140)
    at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
    at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:41)
    at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:274)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:182)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:141)
    at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:124)
    at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:77)
    at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:74)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:154)
    at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:38)
    at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:96)
    at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:74)
    at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.run(RunAsBuildOperationBuildActionRunner.java:50)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:44)
    at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:79)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:44)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
    at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:62)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:34)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
    at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
    at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:46)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:81)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin [id 'com.tencent.matrix-plugin']
    at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:160)
    at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:130)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyType(DefaultObjectConfigurationAction.java:120)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$200(DefaultObjectConfigurationAction.java:38)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$3.run(DefaultObjectConfigurationAction.java:86)
    at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:143)
    at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:46)
    at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.java:34)
    at org.gradle.api.Script$apply$1.callCurrent(Unknown Source)
    at build_3x3nkhfpend1rnu8qf5n420jr.run(/Users/wankey/Documents/GitHub/Scavenger/android/app/build.gradle:9)
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
    ... 102 more
    Caused by: java.lang.NullPointerException: Cannot invoke method create() on null object
    at com.tencent.matrix.plugin.MatrixPlugin.apply(MatrixPlugin.groovy:38)
    at com.tencent.matrix.plugin.MatrixPlugin.apply(MatrixPlugin.groovy)
    at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:42)
    at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:50)
    at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:174)
    at org.gradle.api.internal.plugins.DefaultPluginManager.access$300(DefaultPluginManager.java:50)
    at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:264)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
    at org.gradle.api.internal.plugins.DefaultPluginManager$2.execute(DefaultPluginManager.java:152)
    at org.gradle.api.internal.plugins.DefaultPluginManager$2.execute(DefaultPluginManager.java:149)
    at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:48)
    at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:149)
    ... 112 more

`

Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113] Error while Installing APK

异常类型:app运行时异常/编译异常
安装异常
手机型号:如:Nexus 5(如是编译异常,则可以不填)
模拟器 x86版本
手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)
Android P
matrix版本:如:0.4.5
0.4.5
gradle版本:如:2.10
3.0.1
问题描述:如:在android O 出现系统不兼容
Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
Error while Installing APK

StackOverflowError

Issue /提问须知

在提交 issue 之前,我们应该先查询是否已经有相关的 issue 以及常见问题。提交 issue 时,我们需要写明 issue 的原因,以及编译或运行过程的日志。issue 需要以下面的格式:

异常类型:app 运行时异常/编译异常

手机型号:如: Nexus 5(如是编译异常,则可以不填)

手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)

matrix版本:如: 0.4.7

gradle版本:如: 3.0.0

问题描述:如:在 android O 出现系统不兼容 

堆栈/日志:
1. 如是编译异常,请在执行 gradle 命令时,加上 --stacktrace;
2. 日志我们需要过滤" Matrix. "关键字;

提问题时若使用不能用/没效果/有问题/报错此类模糊表达,但又没给出任何代码截图报错的,将绝对不会有任何反馈。这种 issue 也是一律直接关闭的,大家可以参阅提问的智慧

Matrix 是一个开源项目,希望大家遇到问题时要学会先思考,看看 Sample 与 Matrix 的源码,更鼓励大家给我们提 pr .

Drop armeabi support

armeabi has been deprecated, the latest ndk can't compile on it.

Also armeabi-v7a is compatible with armeabi.

添加matrix-plugin后,app运行时崩溃

在将matrix-plugin添加到app运行后,app会崩溃。
stackrace如下:
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/android/kid//UserInfo$Info;
at com.android.kid.UserInfoManager$2.doInBackground(UserInfoManager.java:234)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
... 3 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.android.kid.UserInfo$Info" on path: DexPathList[[zip file "/data/app/com.android.kid-mRwOdZgEI_UabtsV4LmFvw==/base.apk"],nativeLibraryDirectories=[/data/app/com.android.kid-mRwOdZgEI_UabtsV4LmFvw==/lib/arm, /system/fake-libs, /data/app/com.android.kid-mRwOdZgEI_UabtsV4LmFvw==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 6 more
Suppressed: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/protobuf/GeneratedMessage;
at dalvik.system.DexFile.defineClassNative(Native Method)
at dalvik.system.DexFile.defineClass(DexFile.java:282)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:275)
at dalvik.system.DexPathList$Element.findClass(DexPathList.java:677)
at dalvik.system.DexPathList.findClass(DexPathList.java:466)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:91)
at java.lang.reflect.Method.invoke(Native Method)
at com.bytedance.frameworks.plugin.core.DelegateClassLoader.findClass(DelegateClassLoader.java:62)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:367)
... 7 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.protobuf.GeneratedMessage" on path: DexPathList[[zip file "/data/app/com.android.kid
-mRwOdZgEI_UabtsV4LmFvw==/base.apk"],nativeLibraryDirectories=[/data/app/com.android.kid
-mRwOdZgEI_UabtsV4LmFvw==/lib/arm, /system/fake-libs, /data/app/com.android.kid-mRwOdZgEI_UabtsV4LmFvw==/base.apk!/lib/armeabi-v7a, /system/lib, /system/vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 17 more

执行ApkChecker.jar的时候报错

执行ApkChecker.jar的时候报错
环境:win10
image
{
"--apk":"C:/ibus/android/Android/app/release/release.apk",
"--mappingTxt":"C:/ibus/android/Android/app/build/outputs/mapping/release/mapping.txt",
"--resMappingTxt":"C:/ibus/android/Android/app/build/outputs/mapping/release/resources.txt",
"--output":"C:/Users/starry/Desktop/outputs/apk-checker-result",
"--format":"dt.html",
"--formatConfig":
[
{
"name":"-countMethod",
"group":
[
{
"name":"Android System",
"package":"android"
},
{
"name":"java system",
"package":"java"
},
]
}
],
"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":"-unusedResources",
"--rTxt":"C:/ibus/android/Android/app/build/intermediates/symbols/release/R.txt",
"--ignoreResources"
:["R.raw.",
"R.style.
",
"R.attr.",
"R.id.
",
"R.string.ignore_"
]
},
{
"name":"-unusedAssets",
"--ignoreAssets":["
.so" ]
}
]
}

扫描出不包含alpha通道的图片这里怎么优化apk大小呢?

Issue /提问须知

在提交 issue 之前,我们应该先查询是否已经有相关的 issue 以及常见问题。提交 issue 时,我们需要写明 issue 的原因,以及编译或运行过程的日志。issue 需要以下面的格式:

异常类型:app 运行时异常/编译异常

手机型号:如: Nexus 5(如是编译异常,则可以不填)

手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)

matrix版本:如: 0.4.7

gradle版本:如: 3.0.0

问题描述:如:在 android O 出现系统不兼容 

堆栈/日志:
1. 如是编译异常,请在执行 gradle 命令时,加上 --stacktrace;
2. 日志我们需要过滤" Matrix. "关键字;

提问题时若使用不能用/没效果/有问题/报错此类模糊表达,但又没给出任何代码截图报错的,将绝对不会有任何反馈。这种 issue 也是一律直接关闭的,大家可以参阅提问的智慧

Matrix 是一个开源项目,希望大家遇到问题时要学会先思考,看看 Sample 与 Matrix 的源码,更鼓励大家给我们提 pr .

MethodBeat类方法疑问

代码疑问:
public class MethodBeat implements IMethodBeat, ApplicationLifeObserver.IObserver {
/**
* hook method when it's called in.
*
* @param methodId
*/
public static void i(int methodId) {
if (isBackground) {
return;
}
...
}

/**
* hook method when it's called out.
*
* @param methodId
/
public static void o(int methodId) {
if (isBackground || null == sBuffer) {
return;
}
...
}
/
*
* when the special method calls,it's will be called.
*
* @param activity now at which activity
* @param isFocus this window if has focus
*/
public static void at(Activity activity, boolean isFocus) {}

}

这三个方法在哪里被调用了...
全局搜索了下 没有找到

-The Resource declarations file 'R.txt' is not lega

Issue /提问须知

在提交 issue 之前,我们应该先查询是否已经有相关的 issue 以及常见问题。提交 issue 时,我们需要写明 issue 的原因,以及编译或运行过程的日志。issue 需要以下面的格式:

异常类型:app 运行时异常/编译异常

手机型号:如: Nexus 5(如是编译异常,则可以不填)

手机系统版本:如:Android 5.0 (如是编译异常,则可以不填)

matrix版本:如: 0.4.7

gradle版本:如: 3.0.0

问题描述:如:在 android O 出现系统不兼容 

堆栈/日志:
1. 如是编译异常,请在执行 gradle 命令时,加上 --stacktrace;
2. 日志我们需要过滤" Matrix. "关键字;

提问题时若使用不能用/没效果/有问题/报错此类模糊表达,但又没给出任何代码截图报错的,将绝对不会有任何反馈。这种 issue 也是一律直接关闭的,大家可以参阅提问的智慧

Matrix 是一个开源项目,希望大家遇到问题时要学会先思考,看看 Sample 与 Matrix 的源码,更鼓励大家给我们提 pr .

9.0运行StartUpTracer无结果

异常类型:9.0运行StartUpTracer无结果

手机型号:pixel、oneplus 6T

手机系统版本:9.0

matrix版本: 0.4.7

gradle版本:4.2.1

问题描述:9.0运行StartUpTracer无结果。打开app之后,HackCallback中的handleMessage无法拦截msg.what为159的message,导致sApplicationCreateEndTime为0。并且StartUpTracer中appCreateTime<0,无法调用StartUpReportTask返回结果。

关于elfhook_close问题

目前看代码发现在以下文件中均存在调用elf_open之后,提前return并未走到elf_close的场景,请问是否会存在内存泄露问题?谢谢。
io_canary_jni.cc
sqlite3_profile_hook.cc

taskDescription:Unzip the apk to dest path

命令:java -jar matrix-apk-canary-0.4.7.jar --apk ./app-debug.apk --format mm.json
得到的结果是apk中包含的文件按类型统计,得到的json结果中
apk的total-size为3668342,而各类文件(.so,.dex,.arsc......)的total-size总和为3603336,小于apk的total-size,这是因为?不应该是等于apk的total-size吗?

ResourcePlugin的疑问

Issue /提问须知

异常类型:app 运行时异常

手机型号:小米8

手机系统版本:9.0

matrix版本:0.4.8

gradle版本: 3.2.1

问题描述: 
     创建内部类Handler的内存泄漏 Resourceplugin没有任何的回调,sampleApp中的static activity 则会正常提示

couldn't find "libio-canary.so"

异常类型:app运行时异常

手机型号:如:vivo nex

手机系统版本:Android8.0

matrix版本:0.4.5

gradle版本:3.2.1

问题描述:无法运行couldn't find "libio-canary.so"

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.-1/base.apk"],nativeLibraryDirectories=[/data/app/com.-1/lib/arm, /data/app/com.-1/base.apk!/lib/armeabi-v7a, /system/lib, /vendor/lib]]] couldn't find "libio-canary.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:984)
at java.lang.System.loadLibrary(System.java:1530)
at com.tencent.matrix.iocanary.core.IOCanaryJniBridge.loadJni(IOCanaryJniBridge.java:95)
at com.tencent.matrix.iocanary.core.IOCanaryJniBridge.install(IOCanaryJniBridge.java:43)
at com.tencent.matrix.iocanary.core.IOCanaryCore.initDetectorsAndHookers(IOCanaryCore.java:83)
at com.tencent.matrix.iocanary.core.IOCanaryCore.start(IOCanaryCore.java:49)
at com.tencent.matrix.iocanary.IOCanaryPlugin.start(IOCanaryPlugin.java:62)
at com..AppApplication.initMatrix(AppApplication.java:95)
at com..AppApplication.onCreate(AppApplication.java:54)

关于微信C++内存泄漏检测工具开源

前段时间在微信公众号中看到过微信内存优化的文章,里面提到目前微信有一套检测Native内存泄漏的工具,性能开销很小检测效率高,不只是否能开源,以解决目前Android上Native内存泄漏定位困难的处境。谢谢

缺少arm64-v8a so库

异常类型:app 运行时异常

手机系统版本:Android 9

Android Studio版本:3.2.1
NDK 版本:18.1

matrix版本:0.4.10

gradle版本:4.4

问题描述:缺少arm64-v8a so库,couldn't find "libSqliteLint-lib.so"

E/AndroidRuntime: Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/***-EceQZsEfONFxYG1zekFRSA==/***.apk!/lib/arm64-v8a, /system/lib64]]] couldn't find "libSqliteLint-lib.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
        at java.lang.System.loadLibrary(System.java:1669)
        at com.tencent.sqlitelint.SQLiteLintNativeBridge.loadLibrary(SQLiteLintNativeBridge.java:37)
        at com.tencent.sqlitelint.SQLiteLint.<clinit>(SQLiteLint.java:38)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.