A gradle plug-in that shares the execution time of a statistical method (technical points: gradle plug-in, asm, code generation)

explain:

1. At present, the project is still under development, but it can be used in the Debug stage. At present, version 1.0.2 is gradually improving

2. Technically speaking, it is not difficult to achieve, but there are many pitfalls in the process

3. According to the plan, the project is divided into two parts

Gradle plug-in part: This is the project
Python data visualization section: not yet started

purpose

The running time of the statistical method is as follows:

Quick use

1. In the root project build Add my maven warehouse address to the gradle file and set the plug-in dependency

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        //1. My maven private library address
        maven {
            allowInsecureProtocol = true
            url 'http://161.117.195.45:6677/repository/sand_repo/'
        }
        google()
        mavenCentral()
        maven { url 'https://dl.google.com/dl/android/maven2/' }
        maven { url 'https://www.jitpack.io' }
        jcenter()
        maven { url 'https://jcenter.bintray.com' }

    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.4"
        classpath "com.sand.group:mt:1.0.2" //2. Dependent plug-ins
    }
}

2. In app build Apply plug-ins in gradle and configure plug-in parameters

plugins {
    id 'com.android.application'
    id 'com.sand.mt'//Application plug-in
}

//MTConfig configured parameters for plug-ins to call
MTConfig {
    //Configure the package path where the automatically generated MTCallBack class is locked
    mtCallBackPackage="com.mt.autogen.callback"
    //Configure which classes under packages need to be instrumented (the methods under these packages will be instrumented)
    //This configuration means com sand. apm. Remove the blacklist, excludeclasses and excludemethods of the classes under the mtdemo package
    //All methods will be inserted. If a class is inserted, class not found appears during operation
    //Please add its class name to excludeClasses
    pkgs = [
            "com.sand.apm.mtdemo"
    ]
    whiteList = []//All the methods in the white list are inserted
    blackList = []//There are no methods in the blacklist
    excludeMethods = [//These methods do not insert piles
                      "<init>", //Construction method without pile insertion
                      "<clinit>" //Static domain constructors are not instrumented
    ]
    excludeClasses = [//The classes here do not need to be inserted, and the class file name is written directly
            "BuildConfig.class",
            "Tool.class"
    ]
}

After configuring these parameters, execute synchronization and make. If nothing happens, you will see the automatically generated code under src/main/java. (if you fail at one time, try several more times, it's really not good. Welcome to leave a message)

principle

Use the gradle plug-in to insert statistical code at the beginning and end of the method call of the compiled class file. The actual effect is as follows

Code before pile insertion:

public static void method1(){
    System.out.println("I am method1");
}

Decompile code after pile insertion

public static void method1() {
    long currentTimeMillis = System.currentTimeMillis();
    System.out.println("I am method1");
    MTCallBack.mtDone(currentTimeMillis);
    }

MTCallBack here is a dynamically generated MTCallBack at compile time Java file. The code generated by default is as follows. You can write any code in this class, such as collecting various information of App runtime

public class MTCallBack{

   public String tag="mt";
   public static void mtDone(long start) {

      long end = System.currentTimeMillis();
      long cost = end - start;
      StackTraceElement[] sts = Thread.currentThread().getStackTrace();
      //sts[3] is the method in which mtDone is called. You can also loop up to query deeper stack levels
      String currentMethodName = sts[3].getClassName() + "." + sts[3].getMethodName();
      String mtLog = currentMethodName + " time consuming:" + cost + " ms,Thread.name:" +    Thread.currentThread().getName();

      if (cost < 100) {
         Log.w("mt",mtLog);
      } else {
         Log.e("mt",mtLog);
      }
   }
}

Current progress, existing problems and future plans

Current progress

It has passed the test on Windows, and the Mac has not had time to test. It is expected to be completed soon

Existing problems

It can only be used in debug mode for the time being (considering the performance problems and ensuring the stable operation of the App), and it will be gradually improved in the later stage

Future plans

I developed this little plug-in to replace the flame diagram of Android Studio Profiler (because I think the flame diagram is not intuitive, and it is a little troublesome, and can not compare data for many times). It is expected to develop in this direction in the future (the data is more intuitive and convenient, and enriches the default functions of MTCallBack). If you are interested in participating in this small project, you are welcome to leave a message.

Source address: https://github.com/woshiwzy/APM_MT

Tags: Android

Posted by MP145 on Sun, 17 Apr 2022 21:20:54 +0930