FPS stands for Frames Per Second. In this tutorial we will look at some of the best Android CountryPicker libraries and how to use them.

1. SilenceDut/fpsviewer

A Real-time Fps Tool for Android.

A visualization tool that can display fps, average frame rate over a period of time, and frame rate range ratio in real time, and can get stuck stack. Low intrusion, by sampling the stack in asynchronous threads, there is no code intrusion, performance consumption can be ignored, the abnormal data of performance monitoring items is collected and analyzed, and the output is organized to display the corresponding stack, thereby helping developers to develop higher quality. application.

Common solutions for analyzing and locating stuck

System Tools

1. TraceView

At present, the cpu-profile tool in Android Studio is generally used or the TraceCompat.beginSection() trace log is generated. The accuracy is high. This analysis method is only suitable for qualitative analysis, because the tool consumes a lot of CPU, and there are many fake janks, which greatly affect the performance and show the time-consuming and actual The time-consuming deviation is very large, and it is not easy to use in the usual development process. It is impossible to open it in real time, and it is impossible to view the fps.

Kotlin Android Fragments Example

Kotlin Android Fragments Example
Kotlin Android Fragments Example

2. Systrace Systrace is used to detect the running status of each component of the android system over time, and can prompt how to effectively repair the problem. It is mainly inclined to analyze the status of the entire system for a period of time, and cannot locate the specific code.

3. The command line adb shell dumpsys SurfaceFlinger --latency com... package name is used to calculate the frame rate for a period of time, the freeze stack cannot be obtained, only a period of time

The solutions provided by the above systems can generally only be analyzed in a relatively short period of time, and it is also very inconvenient in the usual development process.

Third-party library solutions

  • Matrix-TraceCanary WeChat's stuck detection solution adopts the ASM instrumentation method, which supports the positioning of fps and stack acquisition, but it needs to analyze the stack by itself according to the method id of asm instrumentation, with high positioning accuracy and low performance consumption. It is a pity that there is currently no interface display, which is intrusive to the code. Consider using it online.

  • The main principle of BlockCanaryEx is to use the log printed in loop(), the log printed in loop() can be seen in this blog by Hongyang. Android UI performance optimization detects UI stuck in the application , supports method sampling, and knows all methods in the main thread The execution time and the number of executions are high, because it needs to obtain the status of the CPU and some systems, which consumes a lot of performance and does not support fps display. Especially when a freeze is detected, the interface will freeze for a long time. This tool was used in our previous projects.

  • FPSViewer uses Choreographer.FrameCallback to monitor the calculation of freeze and Fps, and asynchronous threads perform periodic sampling. When the current frame time exceeds the user-defined threshold, the frame is analyzed and saved, which does not affect the normal process, and will be performed when needed. display, positioning.

fpsviewer Features

  1. Lossless FPS real-time display, the average frame rate and frame rate ratio of a period of time, using Choreographer.FrameCallback fun doFrame(frameTimeNanos: Long) method callback to obtain data to calculate the time consumed by each frame, high real-time performance and no additional data acquisition and no other performance consumption, open and Closing fpsviewer has much less effect on frame rate than 1 frame. Supports the display of the average frame rate and frame rate ratio over a period of time, which can be used for comparison before and after performance optimization.

  2. More detailed stack information is convenient for locating the source of the freeze, sampling method or stack, rather than acquiring the stack at the moment when the freeze occurs, which may cause stack offset and affect the accuracy. The asynchronous thread is at a custom sampling time (generally >30ms) The time-consuming of stack acquisition is very small each time. Storage analysis is only required for sending a freeze. It is also in an asynchronous thread, which has no impact on the main thread and negligible impact on the overall CPU. Generally, multiple stack information is obtained, sorted according to the number of occurrences during this period.

  3. Supports custom stack tags, similar to TraceCompat.beginSection() , to facilitate the analysis of specific business stutters, such as a list, the stutter time-consuming during the startup of an Activity or App.


[real-time fps]


[Function selection]


Clicking the analysis icon shows:


Click on the specific stuck point in the above figure to view the detailed stack information as follows: [Detailed stack map] image

Click the bug icon on the homepage or the above image to display a list of freezes for a period of time image

You can long press to delete or enter the detailed stack interface to mark as resolved, click to enter the detailed stack information interface, TestSection is a custom TAG.

Step 1: Install it

First Add it in your root add build.gradle at the end of repositories:

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }

Then Add the dependency:

dependencies {
    debugImplementation "com.github.silencedut.fpsviewer:fpsviewer:latestVersion"
    releaseImplementation "com.github.silencedut.fpsviewer:fpsviewer-no-op:latestVersion"

Step 2: Initialize, add Section as needed

interface IViewer {
    fun initViewer(application: Application,fpsConfig: FpsConfig? = null)
    fun fpsConfig():FpsConfig
    fun appendSection(sectionName:String)
    fun removeSection(sectionName:String)


Read more.


Read Individually.