In mobile application development, we sometimes need to monitor the time-consuming of some processes, such as application startup time, page Jump time, etc., which is not accurate only by naked eyes. We can realize it in several ways. One way is to obtain startup time by shell, one way is to output time by code point tapping, and the other way is to insert a stake. Here is a brief introduction The first two.
I. adb shell am mode
Make the adb shell get the real start time code of the application as follows:
adb shell am start -W [packageName]/[packageName.SplashActivity]
After execution, you will get three times: ThisTime, TotalTime and WaitTime. TotalTime represents the start time of the Application, including the creation process + Application initialization + Activity initialization to the interface display.
II. Code management
The execution time of each method can be accurately obtained through code marking. The relevant codes are as follows:
/** * The time-consuming monitor object records the time-consuming situation of the whole process, which can be used in many places requiring statistics, such as Activity startup time and Fragment startup time. */ public class TimeMonitor { private final String TAG = TimeMonitor.class.getSimpleName(); private int mMonitorId = -1; private HashMap<String, Long> mTimeTag = new HashMap<>(); private long mStartTime = 0; public TimeMonitor(int mMonitorId) { Log.d(TAG, "init TimeMonitor id: " + mMonitorId); this.mMonitorId = mMonitorId; } public int getMonitorId() { return mMonitorId; } public void startMonitor() { //Clear the previous data every time you restart to avoid statistical errors if (mTimeTag.size() > 0) { mTimeTag.clear(); } mStartTime = System.currentTimeMillis(); } /** * Record the time consumption of a certain tag every time you hit a point */ public void recordingTimeTag(String tag) { //If the same tag has been saved, clear it first if (mTimeTag.get(tag) != null) { mTimeTag.remove(tag); } long time = System.currentTimeMillis() - mStartTime; Log.d(TAG, tag + ": " + time); mTimeTag.put(tag, time); } public void end(String tag, boolean writeLog) { recordingTimeTag(tag); end(writeLog); } public void end(boolean writeLog) { if (writeLog) { //Write to local file } } public HashMap<String, Long> getTimeTags() { return mTimeTag; } }
/** * Click configuration class, which is used to count the time-consuming of each stage and facilitate code maintenance and management. */ public final class TimeMonitorConfig { //Application startup time public static final int TIME_MONITOR_ID_APPLICATION_START = 1; }
/** * A single case is used to manage the time-consuming statistical data. */ public class TimeMonitorManager { private static TimeMonitorManager mTimeMonitorManager = null; private HashMap<Integer, TimeMonitor> mTimeMonitorMap = null; public synchronized static TimeMonitorManager getInstance() { if (mTimeMonitorManager == null) { mTimeMonitorManager = new TimeMonitorManager(); } return mTimeMonitorManager; } public TimeMonitorManager() { this.mTimeMonitorMap = new HashMap<Integer, TimeMonitor>(); } /** * Initialize the dotting module */ public void resetTimeMonitor(int id) { if (mTimeMonitorMap.get(id) != null) { mTimeMonitorMap.remove(id); } getTimeMonitor(id); } /** * Get puncher */ public TimeMonitor getTimeMonitor(int id) { TimeMonitor monitor = mTimeMonitorMap.get(id); if (monitor == null) { monitor = new TimeMonitor(id); mTimeMonitorMap.put(id, monitor); } return monitor; } }
Generally, the points are:
Application lifecycle nodes, such as onCreate of application, callback function of Activity or Fragment (onCreate, onResume, etc.);
Important initialization methods are needed at startup, such as database initialization, reading some local data, etc.
Other time-consuming algorithms, etc.
For example, add monitoring at startup and statistics at Application and the first Activity.
Application:
@Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); TimeMonitorManager.getInstance().resetTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START); } @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).recordingTimeTag("Application-onCreate"); }
First Activity:
@Override protected void onCreate(Bundle savedInstanceState) { TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).recordingTimeTag("SplashActivity-onCreate"); super.onCreate(savedInstanceState); init(); TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).recordingTimeTag("SplashActivity-onCreate-Over"); } @Override protected void onStart() { super.onStart(); TimeMonitorManager.getInstance().getTimeMonitor(TimeMonitorConfig.TIME_MONITOR_ID_APPLICATION_START).end("SplashActivity-onStart", false); }