Preface: In the last article, we briefly introduced the next bytecode piling process. Here we mainly introduce how to achieve the statistical method time by using a one-line annotation. We have this requirement when optimizing app startup time, although it can be viewed through profile.
javassit
Introduction: Javassist is a dynamic class library that can be used to inspect, modify, and create Java classes “on the go.” It is similar to, but more powerful than, reflection, which comes with the JDK.
Common types:
-
ClassPool: javassist’s ClassPool. You can use the ClassPool class to track and control the classes you are working on. It works much like a JVM class loader.
-
CtClass: CtClass provides methods to examine class data (such as fields and methods) and to add new fields, methods, and constructors to the class, as well as to change classes, superclasses, and interfaces. However, Javassist does not provide any methods to remove fields, methods, or constructors from a class.
-
CtField: Used to access the domain
-
CtMethod: Used to access methods
-
CtConstructor: Used to access a constructor
gradle transform
GetName: Specifies the Transform name. This name is not the final Transform name, which is reprocessed by the TransformManager
GetInputTypes: Specifies the input type of the Transform, which can be used as a means of input filtering
-- CLASSES means working with compiled bytecode, either jar packages or directories -- RESOURCES means working with standard Java RESOURCESCopy the code
GetScopes: Specifies the scope of the Transform
- PROJECT only works with the current PROJECT - SUB_PROJECTS only works with sub-projects - PROJECT_LOCAL_DEPS only works with local dependencies of the current PROJECT, such as JARS, Aar - EXTERNAL_LIBRARIES handles only external dependencies. PROVIDED_ONLY handles only local or remote provided dependencies. TESTED_CODE handles only test codeCopy the code
IsIncremental: indicates whether the build isIncremental.
Transform: the core method used for custom processing. In this method, we can get the path of the.class file, the path of the JAR package, the path of the output file, etc. We can get the files and operate on them
inputs.each { TransformInput input -> input.directoryInputs.each { DirectoryInput directoryInput -> if (directoryInput.file.isDirectory()) { println "==== directoryInput.file = " + directoryInput.file directoryInput.file.eachFileRecurse { File file -> // ... }} // After processing the input file, The output to the next task def dest = outputProvider. GetContentLocation (directoryInput. Name, directoryInput contentTypes, directoryInput.scopes, Format.DIRECTORY) FileUtils.copyDirectory(directoryInput.file, dest) } input.jarInputs.each { JarInput jarInput -> println "------=== jarInput.file === " + jarInput.file.getAbsolutePath() File tempFile = null if (jarInput.file.getAbsolutePath().endsWith(".jar")) { // ... } /** * Duplicate the output file, because it might have the same name, overwriting */ def jarName = jarinved.name def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath()) if (jarName.endsWith(".jar")) { jarName = jarName.substring(0, JarName. Length () - (4)} / / processing jar bytecode injection processing def dest = outputProvider. GetContentLocation (jarName + md5Name, jarInput.contentTypes, jarInput.scopes, Format.JAR) FileUtils.copyFile(jarInput.file, dest) } }Copy the code
Implementation steps
1. The annotation class
2. Gradle plugin derregisters Transform
To use gradle plugin, please go to Gradle plugin
3. Implementation steps of the transform operation file
4. After obtaining the file, use the Javassit operation
5. Upload Gradle plugin and annotations to Maven for app dependency reference
Gradle plugin for Android
6. Rebuild
You can see that the test method in the class file has been inserted with the code we want
7. Run the results
Afterword.
Here only provides a startup optimization to do time detection scenarios, there can be annotated to do non-trace buried points, some of the user’s main process operation link analysis and so on.
The code address
The source code