What is the most precise way to measure startup time of an Android app?
By startup time I mean the difference between 2. and 3. :
It is possible to implement time tracking using the next code:
Override your Application
:
public class CustomApplication extends Application {
public final static long APP_START_TIME = System.currentTimeMillis();
/**
* Do all other application stuff
*/
}
And add few rows to your main Activity
:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View contentView = findViewById(android.R.id.content);
contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= 16) {
contentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
contentView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
long launchTime = System.currentTimeMillis() - CustomApplication.APP_START_TIME;
Log.e("TEST", "App launch time = " + launchTime);
}
});
}
}
And don't forget to define your custom application in Manifest
:
<application
android:label="@string/app_name"
android:name=".CustomApplication" >
</application>
Important: You have to kill your application before launch, because Application stores static variable which tracks initial time.
I think this has been built into Firebase Console, under performance now
I understand I am too late to answer, nonetheless, this precisely answers the question.
This information gets logged on Logcat by default for API version 19 or higher.
From Android 4.4 (API level 19), logcat includes an output line containing a value called Displayed. This value represents the amount of time elapsed between launching the process and finishing drawing the corresponding activity on the screen.
ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms
The key is looking for it in the right place -
If you’re tracking logcat output from the command line, or in a terminal, finding the elapsed time is straightforward. To find elapsed time in Android Studio, you must disable filters in your logcat view. Disabling the filters is necessary because the system server, not the app itself, serves this log.
The extracts are from the documentation.
One possibility would be is to save the time at the beginning of the onCreate()
method and at the end of the onCreate() method
and then subtract those times from each other to get the time taken to initialize the app.
Wrap the entire onCreate()
method in a TimingLogger
. Just put this at the beginning:
TimingLogger timings = new TimingLogger(TAG, "methodA");
and this at the end:
timings.dumpToLog();
If you want to drop times at some intermediate step, you can do timings.addSplit("name");
to get the time it took to get to that step.
I'm going to interpret your question as 'Is my app startup time fast enough. How can I check I have done everything I can do?'
The startup time is largely a false metric as it will vary across devices and ROMs. I guess what you're most likely to be interested in is how much of your code is taking a long time to execute and what is potentially blocking the main thread.
I've found the most effective way of doing this is to use Traceview on the app start and then reviewing how long it takes the method to execute and if there are any gaps on the main thread.
Start tracing:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Debug.startMethodTracing("startup");
}
}
Stop tracing:
@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Debug.stopMethodTracing();
}
Once the trace has been collected, you should be able to see anything that is having a major impact on startup time. In my case, seen below, there was a big gap on the UI thread where is was being blocked.
It transpired that both Crashlytics and Coremetrics were requiring a call to randomUUID()
which was then being synchronized across threads and blocking the main thread. The solution was just to spin up a new thread to initialise the Coremetrics code.
This is something I would not have otherwise picked up with just measuring the startup time, but it actually sped up the app 'startup time' by a few hundred milliseconds.
Here's another snapshot after spinning off a separate thread for Coremetrics initialisation: