The article directories

Matrix is an APM (Application Performance Manage) developed by wechat and used daily. Currently, it is mainly running on Android platform

I. Official address

  • Tencent/matrix
  • Meaning parsing of Matrix output content
  • Matrix ResourceCanary
  • Matrix ApkChecker
  • Matrix SQLiteLint
  • Matrix- Frequently asked Questions

Second, Demo analysis

Just look at the core code, and we will explain related variables later:

  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();
Copy the code

Iii. Overall structure

  • matrix-android-lib
  • matrix-gradle-plugin
    • matrix-arscutil
    • matrix-commons
  • matrix-apk-canary
  • matrix-resource-canary
  • matrix-trace-canary
  • matrix-sqlite-lint
  • matrix-io-canary
    • matrix-android-commons

To tell the truth, if you have seen another APM open source project Kyson/AndroidGodEye, it will be easy to grasp the overall design ideas, here is an analysis for AndroidGodEye :(4.2.46) AndroidGodEye source code overall structure analysis

It is suggested that further details should be understood on the basis of grasping the overall frame structure.

As matrix now describes, it provides runtime monitoring capabilities:

  1. Resource Canary:
    1. Leakage of the Activity
    2. Bitmap redundancy
  2. Trace Canary
    1. Interface fluency
    2. Start the time-consuming
    3. Page Switching Time
    4. Slow function
    5. caton
  3. SQLite Lint: Automatically detects the quality of use of SQLite statements according to official best practices
  4. IO Canary: detects file I/O problems
    1. File I/O Monitoring
    2. Closeable Leak monitoring

Four, matrix – android – lib

  • A Plugin is defined as an abstraction of some monitoring capability
  • Issue Indicates a monitored event that occurs
  • Report An implementation of the observer pattern used to notify observers when an Issue is found
  • Matrix singleton pattern implementation, exposure to external interfaces
  • Matrix-config. XML configuration items related to monitoring
  • IDynamicConfig is open to user – defined monitoring configuration items, which are actually held by each Plugin

4.1 Plugin monitoring capability

  • IPlugin is an abstraction of monitoring capabilities
  • PluginListener is the ability of a monitoring module to initialize, start, stop, discover problems, and so on. Users can implement it themselves and inject it into Matrix
  • Plugin
    1. Default implementation of the IPlugin to trigger the associated PluginListener lifecycle
      • This means that the monitoring capability lifecycle is triggered before the monitoring capability takes action
    2. Implement IssuePublisher. OnIssueDetectListener onDetectIssue method of interface
      • This method will be used when a specific monitoring event occursMatrix.with().getPluginByClass(xxx).onDetectIssue(Issue)Call it this way. Notice that this isThe first method of notification
      • This method internally assigns values to the environment variables associated with the Issue, such as the Plugin information that caused the Issue
      • This method eventually triggers PluginListener#onReportIssue
Public interface IPlugin {/** * is used to identify the current monitor, equivalent to the name index (can also use classname direct index) */ String getTag(); Void init(Application Application, PluginListener PluginListener); /** * Foreground(foreground); /** * foreground (foreground); void start(); void stop(); void destroy(); } public interface PluginListener { void onInit(Plugin plugin); void onStart(Plugin plugin); void onStop(Plugin plugin); void onDestroy(Plugin plugin); void onReportIssue(Issue issue); }Copy the code

4.2 IssuePublisher Monitored event observer

  • Issue Monitored events
    1. Type: indicates the type used to distinguish reports of different types of the same tag
    2. Tag: indicates the tag of the report
    3. Stack: indicates the stack to be reported
    4. Process: indicates the process name of the report
    5. Time: time when an issue occurs
  • IssuePublisher Observer pattern
    • Have a release Listener(often implemented as the Plugin above)
    • Hold a Map of published information to avoid repeated publishing for the same event during a run time
    • In general, monitoring probes of some kind of monitoring tend to inherit this class and call it when an event is detectedpublishIssue(Issue)– > IssuePublisher. OnIssueDetectListener onDetectIssue method of interface – > * * eventually triggerPluginListener#onReportIssue
    • Notice that this is the second notification
  • FilePublisher keeps a local record of published events, avoiding multiple releases of the same event within the duration of a single installation

4.3 Utils Auxiliary ability

  • MatrixLog opens log capabilities to users
  • MatrixHandlerThread Is a common thread, usually used by asynchronous threads to perform certain tasks
  • DeviceUtil Obtain device information
  • The MatrixUtil determines the main thread and other utils

4.4 Matrix External interfaces

public class Matrix { private static final String TAG = "Matrix.Matrix"; / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * the singleton implementation * * * * * * * * * * * * * * * * * * * * * * / private static volatile Matrix sInstance; public static Matrix init(Matrix matrix) { if (matrix == null) { throw new RuntimeException("Matrix init, Matrix should not be null."); } synchronized (Matrix.class) { if (sInstance == null) { sInstance = matrix; } else { MatrixLog.e(TAG, "Matrix instance is already set. this invoking will be ignored"); } } return sInstance; } public static boolean isInstalled() { return sInstance ! = null; } public static Matrix with() { if (sInstance == null) { throw new RuntimeException("you must init Matrix sdk first"); } return sInstance; } / * * * * * * * * * * * * * * * * * * * * * * * * * * * * constructor * * * * * * * * * * * * * * * * * * * * * * / private final Application Application; private final HashSet<Plugin> plugins; private final PluginListener pluginListener; private Matrix(Application app, PluginListener listener, HashSet<Plugin> plugins) { this.application = app; this.pluginListener = listener; this.plugins = plugins; for (Plugin plugin : plugins) { plugin.init(application, pluginListener); pluginListener.onInit(plugin); }} / * * * * * * * * * * * * * * * * * * * * * * * * * * * * control * * * * * * * * * * * * * * * * * * * * * * / public void startAllPlugins () {for (Plugin Plugin: plugins) { plugin.start(); } } public void stopAllPlugins() { for (Plugin plugin : plugins) { plugin.stop(); } } public void destroyAllPlugins() { for (Plugin plugin : plugins) { plugin.destroy(); } } /**************************** get | set **********************/ public Plugin getPluginByTag(String tag) { for (Plugin plugin : plugins) { if (plugin.getTag().equals(tag)) { return plugin; } } return null; } public <T extends Plugin> T getPluginByClass(Class<T> pluginClass) { String className = pluginClass.getName(); for (Plugin plugin : plugins) { if (plugin.getClass().getName().equals(className)) { return (T) plugin; } } return null; } / * * * * * * * * * * * * * * * * * * * * * * * * * * * * other * * * * * * * * * * * * * * * * * * * * * * / public static void setLogIml (MatrixLog. MatrixLogImp imp) { MatrixLog.setMatrixLogImp(imp); }}Copy the code

Five, ResourceCanary memory leak detection

  • Matrix-resource-canary – Analyzer is separated from the leak path detection tool and bimap redundancy analysis
  • Matrix-resource-canary – Android memory leak detection tool
  • Matrix-resource-canary -common Some base utils

Let’s take a look at the official documentation

  • Matrix ResourceCanary

The Matrix memory leak detection is based on LeakCanary (if you are not familiar with this open source project, please check the source code).

Memory leak detection LeakCanary (4.2.39)

  • Leakcanary through Application. RegisterActivityLifecycleCallbacks () method to register a callback object, in all the Activity of onActivityDestroyed () method of life cycle method, Asynchronously start a Watch detection
  • The judgment of whether an Activity leaks depends on the FACT that THE VM will add the recoverable object to the ReferenceQueue of WeakReference association
    • By creating a WeakReference that holds the destroyed Activity, and then actively triggering a GC, if the Activity can be reclaimed, the WeakReference that holds it will be empty. And the recovered Activity will be added to a queue registered with WeakReference in advance after a period of time. This indirectly tells us whether a destroyed Activity can be recycled.
  • If the target object is not observed at the ReferenceQueue after GC, a leak may have occurred
  • Trigger heapdumps. The Listener
    1. Use HeapDumper to export the heap memory. 2. Start the HeapAnalyzerService. After the service is started, call Leakcanary – Analyzer to analyze the heap memory information
    2. Analysis results by hair AbstractAnalysisResultService broadcast mode to another background service

The objects involved are as follows:

  • Leakcanary- Watcher implements the basic memory detection framework, but only implements the monitoring mechanism, how to monitor + how to handle the callback
    • RefWatcher core observer, which holds the following instance objects to implement the memory monitoring mechanism
    • RefWatcherBuilder builds [core viewer], passing in objects 1-6
    • Set retainedKeys; //[core] holds keys for references to be detected and memory leaks generated
    • ReferenceQueue queue; //[core] is used to determine whether an object held by a weak reference has been GC
    • DebuggerControl debuggerControl; [1.debug validator] Is used to check whether the system is debugging. During debugging, memory leak detection is not performed
    • GcTrigger gcTrigger; [2.GC controller] is used to give GC another chance before determining a memory leak
    • HeapDumper heapDumper; [3. Heap information exporter] is used to dump the memory heap in the leak room
    • WatchExecutor watchExecutor; //[4. Deferred execution line city] The thread pool executor that performs memory leak detection
    • HeapDump.Listener heapdumpListener; [5. Heap information analyzer] is used to analyze the dump file generated previously to find the cause of the memory leak
    • ExcludedRefs excludedRefs; //[6. Whitelist map] is used to eliminate memory leaks caused by certain system bugs
  • Leakcanary – Analyzer Provides HeapAnalyzer based on Haha to analyze the dumped memory and return the AnalysisResult, which contains information such as the leak path for developers to locate the memory
    • Leakcanary – Android: This Module is an access point to the Android world to monitor Activity leaks using leakcanary- Watcher for weak reference + manual GC
    • RefWatcherBuilderAndroid Builds the [core viewer] used by Android, passing in android objects 1-6
    • DisplayLeakService background services [AbstractAnalysisResultService] subclass, its onHeapAnalyzed (…). It will be called back when it leaks
    • DebuggerControlAndroid //[1.debug validator] Checks whether the system is debugging. During debugging, memory leak detection is not performed
    • HeapDumperAndroid //[3. Heap information exporter] is used to dump the memory heap in the leak room
    • Package DumpFileHelp //[3.1 IO File directory manager] is used to create and manage files that store heap information
    • WatchExecutorAndroid //[4. Deferred execution line city] A thread pool executor that performs memory leak detection
    • HeapDumpListenerAndroid //[5. Heap information analyzer] is used to analyze the dump file generated previously to find the cause of the memory leak
    • Package AnalyzerService //[5.1] Starts a cross-process background service and calls [Leakcanary – Analyzer] to analyze the heap memory information. The analysis results are broadcast to another background service
    • HeapAnalyzerService A cross-process background service and calls Leakcanary – Analyzer to analyze the heap memory information. The analysis results are broadcast to another background service
    • AbstractAnalysisResultService heap memory to accept a service delivery across processes the background analysis, trigger onHeapAnalyzed (…). Ps: its concrete subclass is constructed when [HeapDumpListenerAndroid] is instantiated
    • ExcludedRefsAndroid //[6. Whitelist map] is used to eliminate memory leaks caused by certain system bugs
  • Leaky ActivityWatcherManager focus on listening Activity, used within the application # registerActivityLifecycleCallbacks methods to monitor onDestory events

Let’s focus on it, the improvements:

  • Optimization of leak detection, the main code incom.tencent.matrix.resource.watcher.ActivityRefWatcher#RetryableTask
    • Add a sentinel object that must be reclaimed to verify that the system did GC
    • Weakreference.get () is directly used to judge whether the object has been recovered to avoid misjudgment due to delay
    • If it is found that an Activity cannot be recovered, repeat the judgment three times, and require that more than two activities have been created since the Activity was recorded before it is considered as a leak, in case the Activity is held by local variables during the judgment, resulting in misjudgment
    • For activities that are judged to be leaking, record their class names to avoid repeating the message that the Activity is leaking
  • To achieve the separation of detection and analysis, the main code incom.tencent.matrix.resource.watcher.ActivityRefWatcher#RetryableTask
    • If mHeapDumper exists, the heap memory is exported to further report or analyze the leak locationmHeapDumpHandler.process(heapDump)—–CanaryWorkerService.shrinkHprofAndReport(context, result);
    • If mHeapDumper does not exist, the heap memory is not exported and Issue is reported directly
  • Tailor and report Hprof to:com.tencent.matrix.resource.CanaryWorkerService
  • Memory leak analysis and image redundancy analysis inActivityLeakAnalyzerDuplicatedBitmapAnalyzerimplementation
  • Modified the reference chain lookup algorithm for LeakCanary to find the shortest reference chain from multiple targets to GC Root in a single call
  • CLIMain is the main entry point for command line analysis tools

Performance overhead:

In the monitoring part, the polling interval is currently set as 1min in the periodic polling stage because it is executed in the background thread. Using the frame rates of the contacts page and moments page as a reference, the average frame rate of ResourceCanary decreases by about 10 frames within 2 minutes (the average frame rate of ResourceCanary is 120 frames per second in the same period when ResourceCanary is not connected). The overhead is not obvious. The Dump Hprof phase is more expensive. During Dump, the whole App will be stuck for about 5 ~ 15s, but considering that the ResourceCanary module is not enabled in the online environment, it is acceptable. I guess there is room for optimization of the time taken to Dump Hprof with some hacks; The pre-processing phase for Hprof takes about 3-20s (depending on the machine performance and the size of the Hprof) and has a memory overhead of about 1.5 times the size of the Hprof, but it is also less disruptive to the normal running of the App because it is done in a separate process and only executed after the Dump of Hprof is triggered. However, to improve the algorithm to minimize the time and memory footprint, or to continue to explore.

Six, IOCanaryPlugin

IO Canary: detects file I/O problems, including:

  1. File IO monitoring A. MAIN_THREAD_IO=1, read the same file repeatedly, read the same stack more than 3 times B. BUFFER_TOO_SMALL=2, read the same file repeatedly, read the same stack more than 3 times C. REPEAT_IO=3, read the file buffer is too small. That is less than 4 k
  2. Closeable Leak monitor D. CLOSE_LEAK=4, file Leak

The overall idea is:

  1. The IOCanaryPlugin holds the probe class IOCanaryCore to perform related start and stop actions

  2. IOCanaryCore

    1. holdConfigInternal storage related configuration information
    2. holdCloseGuardHookerFor file leak detection
    3. holdIOCanaryJniBridgeFor I/O monitoring
    4. holdIOCanaryPluginFor notification when an event occurs
    5. implementationOnJniIssuePublishListenerIs used to trigger the listener when a problem is found at the JNI layer, and eventually a callbackmIoCanaryPlugin.onDetectIssue
  3. CloseGuardHooker file leak detection

    • The implementation principle is mainly the related report events of Hook CloseGuard, and the Matrix monitoring is realized by the detection and reporting of strict mode
    • For those interested, read StrictMode and its usage scenarios

StrictMode, StrictMode, is a runtime detection mechanism provided by Android, used to detect some of the code runtime non-standard operations, the most common scenario is used to discover the main thread IO operation StrictMode implementation involves the following source code:

  • libcore/dalvik/src/main/java/dalvik/system/BlockGuard.java
  • libcore/dalvik/src/main/java/dalvik/system/CloseGuard.java
  • Frameworks/base/core/Java/android/OS/StrictMode. Java Guard has the meaning of “Guard”, the Block is blocking the meaning, for some time-consuming procedures, such as disk read and write, network operation, there is a Guard in monitoring, It is called BlockGuard. If these time-consuming operations cause the main thread to block, BlockGuard will issue a notification; Close corresponds to the file that can be opened. After the file is opened, there is also a guard monitoring the file, which is CloseGuard. If the file is not closed, CloseGuard will notify it
  1. IOCanaryJniBridge

    • Implement related hook and unhook with the help of JNI layer
    • EnableDetector Is used to control whether the following functions are enabled: I/O duration of the main thread, number of repeat reads, and read/write monitoring of small files’ buffer
    • The setConfig command is used to control the following configuration thresholds: I/O time threshold of the main thread, repeat read times threshold, and buffer size threshold of small files
    • static void onIssuePublishUsed to implement callback notifications to the JNI layer
  2. cpp

    • Utils Gets the thread ID, current stack, and other common utils
    • Dector: Defines probes that pass in file information to verify whether a target event has occurred
      • Dector defines basics, such as publishing events, marking events as published, confirming events as published, and so on
      • virtual void Detect(const IOCanaryEnv& env, const IOInfo& file_io_info, std::vector<Issue>& issues) = 0;
      • Main_thread_detector checks the I/O time of the main thread based on input parameters. Exception events are addedissuesIn the
      • Repeat_read_detector verifies the number of repeated reads according to the input parameters and puts abnormal eventsissuesIn the
      • Small_buffer_detector checks small files’ buffer reads and writes based on input parameters and places abnormal eventsissuesIn the
    • core
      • Io_canary_env is used to read configuration thresholds
      • Io_info_collector I/O event Collector. When I/O events occur, Ioinfo is constructed and entered into the map container by calling related functions of the Collector
      • io_canary
        1. Io_info_collector is triggered when corresponding I/O events occur
        2. At the end of the event, the event S collected by the collector is placed into Queue_
        3. Open a while(true) loop that blocks and reads events in Queue_
        4. The read IO events s + build the vector, pass it to each dector for detection and filling, and push it to the Java layerstatic void onIssuePublish
        5. Hold a callback to the upper layerOnPublishIssueCallbackAnd triggering
    • iocanary
      1. doHook()C layer hook related I/o read and write operations and trigger core#io_canary related I/o event listening
        • ProxyOpen
        • ProxyOpen64
        • ProxyRead
        • ProxyWrite
        • ProxyClose
      2. OnIssuePublish()Callback Java layer triggers notification
      3. doUnHookRestore I/O read and write operations

Seven, matrix trace – canary

Trace Canary: Monitors interface smoothness, startup time, page switching time, slow functions, and lag

We see the com. Tencent. Matrix. Trace. TracePlugin, four probe can be observed:

  1. FPSTracer
  2. EvilMethodTracer
  3. FrameTracer
  4. StartUpTracer

Let’s first analyze the overall structure:

  • Config is used to obtain configuration thresholds
  • Constants Related Default value of the configuration threshold
  • TracePlugin
    • · Build the relevant probe object and ApplicationLifeObserver object according to the configuration
    • start()
      1. Called in the main threadFrameBeat.getInstance().onCreate()
      2. Triggers the onCreate life cycle of the associated probe Trace
    • stop()
      1. callFrameBeat.getInstance().onDestroy()
      2. Triggers the onDestroy life cycle of the associated probe Trace
  • core
    • ApplicationLifeObserver
      1. Through the application. RegisterActivityLifecycleCallbacks (this) life cycle relative to the implementation of listening in
      2. Notifies the observer of the following Activity lifecycle events: background switch, page switch, Create \ Resume \ Pause \start, etc
    • FrameBeat implements foreground listening on FrameCallback frame rates and notifies the mFrameListeners list
      1. holdLinkedList<IFrameBeatListener> mFrameListenersThe list of
      2. implementationChoreographer.FrameCallback#doFrameThis is a frame rate notifier, often used for interface stoop listening) that notifies mFrameListeners of the time of this frame rate and the time of the last frame rate
      3. Implement IFrameBeat
        1. onCreate()Register yourself with the ApplicationLifeObserver as an observer; In foreground mode, register itself in the Android system as a frame rate notifier
        2. onDestroy()Unregister itself as an observer to ApplicationLifeObserver; Notify mFrameListeners of the deregister event; Remove mFrameListeners;
        3. addListener/removeListener(IFrameBeatListener listener)
      4. implementationApplicationLifeObserver.IObserverTo have the ability to listen on the Activity lifecycle
        1. OnFront starts to listen on the frame rate
        2. Cancel listening when onBackground is in the background
    • MethodBeat
      1. A static block
        1. Hacker.hackSysHandlerCallback()Start hook related lifecycle functions, whereHackCallbackCreate awareness for activities and applications
        2. The main thread sends releaseBufferMsg with a delay of 30 seconds
      2. Static object sReleaseBufferHandler: Null buffer; STimeUpdateHandler updates diffTime every 5ms
      3. holdLinkedList<IMethodBeatListener> sListeners = new LinkedList<>()The list of
      4. Implement IMethodBeat
        1. onCreate()Register yourself with the ApplicationLifeObserver as an observer; Cancel the main thread releaseBufferMsg; Release updateMsg for a delayed cycle time thread (i.e. start the cycle task)
        2. onDestroy()Unregister itself as an observer to ApplicationLifeObserver; Cancel relevant Msg; Clear the listener
        3. addListener/removeListener(IFrameBeatListener listener)
      5. Implement ApplicationLifeObserver. IObserver to have related ability to monitor the Activity life cycle
        1. UpdateMsg is sent to the foreground for the delayed loop time thread. Cancels updateMsg for delayed loop time threads while in the background
        2. OnActivityCreated and onActivityStarted, while in the background state, send the updateMsg for the time thread
  • hacker
    • HackerInternal use of custom HackCallback, hook up"android.app.ActivityThread"This class is a familiar trigger for local process operations such as activity-related lifecycle
    • HackCallbackThrough dynamic proxyhandleMessage(Message msg)Method to implement the
      1. Activity is used to judge when the animation enters completionHacker#isEnterAnimationCompleteStatic storage
      2. Check ApplicationCreateEnd by monitoring Acitvity, CREATE_SERVICE, RECEIVER, etcHackCallback#isCreatedStatic storage
  • scheduler
    • LazyScheduler A cyclic task that is periodically executedonTimeExpire()
  • listeners
    • IFrameBeat frame frequency receiver capability abstraction
    • IFrameBeatListener inherits a specific probe implementation for analyzing related information
      1. doFrame(long lastFrameNanos, long frameNanos)inChoreographer.FrameCallbackIs triggered to notify the time of two frame rates
      2. cancelFrame()
    • IDoFrameListener A specific frame drop listener that triggers functions in the FrameTracer to asynchronously or synchronously notify frame drops
      1. doFrameSyncSynchronous notification
      2. getHandler + doFrameAsyncAsynchronous notification
    • IMethodBeat An abstraction of notification receiver capabilities related to the execution of system functions
    • IMethodBeatListener inherits an implementation to a specific probe to analyze the relevant information
      1. onActivityEntered
      2. onApplicationCreated
      3. pushFullBuffer
  • Tracer
    • BaseTracer
      1. inheritanceApplicationLifeObserver.IObserver, which gives you the ability to sense the Activity lifecycle
      2. inheritanceIFrameBeatListener, thus having the ability to sense frame rate notification
      3. inheritanceIMethodBeatListenerAnd thus have the ability to perceive relevant system functions
      4. Holds static HashMap

        sTracerMap, all probe tracers currently instantiated
        ,>
      5. SMethodBeat = new MethodBeat()
      6. onCreate()Will be mentioned aboveIObserver\IFrameBeatListener\IMethodBeatListenerRegister with the corresponding actuator
      7. onDestroy()And write off all the listeners mentioned above
      8. sendReportInternally call onDetectIssue() of TracePlugin
    • FrameTracer
      1. holdLinkedList<IDoFrameListener> mDoFrameListenerList = new LinkedList<>()Event listener
      2. implementationdoFrame(xxx,xxx)In thinkNotify mDoFrameListenerList when the frame rate exceeds the threshold 16.67ms twice
      3. implementationViewTreeObserver.OnDrawListenerAnd register itself during the onChange life cycle on the Activity page to implement isDrawing without detection
    • I won’t give you any more examples

From this, we can get the following chain of events:

  1. TracePlugin#initThe singleton ApplicationLifeObserver is built during initialization to listen for the associated Activity lifecycle
  2. TracePlugin#initFrameTracer, StartUpTracer, FPSTracer, EvilMethodTracer probe instances are built during initialization
    1. XxTracer probe instance inherits fromBaseTracer, which builds its internal static object instanceHashMap<Class<BaseTracer>, BaseTracer> sTracerMapMethodBeat sMethodBeat = new MethodBeat()
      1. MethodBeat sMethodBeat = new MethodBeat()Will performMethodBeatA static block inside it
        1. The triggerHacker.hackSysHandlerCallback()Its internal use custom HackCallback, hook up"android.app.ActivityThread"This class is a familiar trigger for local process operations such as activity-related lifecycle
        2. HackCallbackCreate awareness for activities and applications
  3. TracePlugin#start()Called in the main processFrameBeat.getInstance().onCreate()
    1. onCreateRegister yourself FrameBeat as an observer with ApplicationLifeObserver In foreground mode, register itself in the Android system as a frame rate notifier
    2. FrameBeat is also triggered when the frame rate is notifiedLinkedList<IFrameBeatListener> mFrameListenersListening to the list
  4. TracePlugin#start()In the callmFrameTracer.onCreate();
    1. onCreateIn fact, BaseTracer now treats itself asIObserver\IFrameBeatListener\IMethodBeatListenerRegister with the corresponding actuator, so that it has the ability to sense the Activity life cycle, the ability to sense the frame rate notification, and the ability to sense the related system functions
    2. At the same time, implementdoFrame(xxx,xxx)In thinkNotify mDoFrameListenerList when the frame rate exceeds the threshold 16.67ms twice
    3. At the same time, implementViewTreeObserver.OnDrawListenerAnd register itself during the onChange life cycle on the Activity page to implement isDrawing without detection
  5. TracePlugin#start()In the callmEvilMethodTracer.onCreate();
    1. onCreateIn fact, BaseTracer now treats itself asIObserver\IFrameBeatListener\IMethodBeatListenerRegister with the corresponding actuator, so that it has the ability to sense the Activity life cycle, the ability to sense the frame rate notification, and the ability to sense the related system functions
    2. onCreateBuild related thread objects, cyclic task objects, and so on
    3. ANR detection and Normal detection
      1. At the same time, implementdoFrame(xxx,xxx).Cancel the last delayed task and enable a delayed taskThat is to sayIf a function completes during a frame interval, no delay task is triggered; When a delayed task is triggered, it also means that a time-consuming operation has occurred on the main threadAnd specify type. ANR, ANR timeout scenario
      2. At the same time, implementLazyScheduler.ILazyTaskImplement delayed tasks that print current stack information or other analysis (callevilMethodTracer.handleBufferAnd indicate the ANR)
      3. At the same time, implementdoFrame(xxx,xxx), compares the time of two DoFrames. If the time exceeds the threshold, the NORMAL time is considered
    4. STARTUP Time Detection
      1. At the same time, StartUpTracer checks startup time during application startup and invokesevilMethodTracer.handleBufferAnd indicate the STARTUP
    5. Enter test
      1. At the same time, implementonActivityCreatedAnd records the interface entry time
      2. At the same time, implementonActivityEntered, compare the entry time and useevilMethodTracer.handleBufferAnd indicate the Type, Enter
  6. TracePlugin#start()In the callStartUpTracer.onCreate();
    1. onCreateIn fact, BaseTracer now treats itself asIObserver\IFrameBeatListener\IMethodBeatListenerRegister with the corresponding actuator, so that it has the ability to sense the Activity life cycle, the ability to sense the frame rate notification, and the ability to sense the related system functions
    2. At the same time, implementonActivityCreatedListen for the first FirstActivityName
    3. At the same time, implementonActivityEnteredTo detect the slow startup function and report startup monitoring
  7. TracePlugin#start()In the callFPSTracer.onCreate();Statistics on the frame rate of Acitivty

Eight, matrix – sqlite – lint

SQLiteLint detects when APP is running, and most detection algorithms are independent of data volume, that is, they do not depend on data state on the line. Whenever you trigger the execution of an SQL statement, SQLiteLint will help you review whether the statement was written incorrectly. This can be done in the development, testing, or grayscale phases.

SqliteLint analyzes the performance of SQL statements based on the structure of SQL statements and the structure of the database by weaving into the relevant Checker

Source code involves more, this article temporarily not analysis, left to the next chapter

Nine, APK Checker

Matrix-apkchecker is provided as a JAR package, which can be run by running the Java -jar ApkChecker.

  • Better usability: Provided as a JAR package, it is easier to apply to continuous integration systems to track and compare changes between each APK release
  • More check and analysis functions: In addition to the function of APKAnalyzer, it also supports counting R classes contained in APK, checking whether there are multiple dynamic libraries statically linked to STL, searching useless resources contained in APK, and supporting custom check rules, etc
  • Output checks are more detailed: support for visual HTML format, JSON for easy parsing, custom output, and more

See the official documentation: Matrix ApkChecker

To be continued…