Android性能优化——启动篇1:Understanding App Launch Time了解应用启动
开始计时【哔】 你知道应用的启动时间意味着什么吗？如果你的应用启动超出了四分之一秒，用户很可能会关掉它干别的事情去了。【哔】我是 Colt McAnlis。忽视应用在启动期间所做的事情将会让它有很严重的性能问题。
从技术层面，整个启动过程是这样的：当用户启动了你的应用，系统会做些加载应用信息以及创建单独的应用进程的工作。从这开始系统进程就会显示一个Start Window一直显示到应用开始运行。同时，应用进程会创建Application对象启动主线程。从这开始应用的启动界面将会被初始化，创建，填充布局，最后绘制。只有在应用绘制第一帧之后，系统进程才会将Start Window置换为具体界面。
第一个Displayed Time输出语句。在Android 4.4版本后，Logcat可以打印从进程启动到界面最终被绘制的时间总和。这很有用，因为它给了你一个应用启动大致的时间。顺便说一下，记着，想要在Android Studio中看到这个值，你需要关掉Logcat的过滤器。
第三个方法是Tracing。Display Time和reportFullyDrawn()可以给出一个明确的应用加载时间，方便我们去分析。但是他们没有显示出在整个启动过程中某些部分为什么会慢的具体细节。想要对这一部分深入观察，可以使用Android Studio自带的Tracing工具。
And go. [BEEP]You know what this timer means? Every quarter second a user spends staring at a blank screen instead of interfacing with your app is a quarter second more they’re willing to close your app and give their attention to something else.[BEEP] My name is Colt McAnlis, and misunderstanding all the complex things that happen during your app startup can lead to some serious performance problems.
Now, see, Android is pretty smart when it comes to understanding human performance perception. As soon as the user launches your application, Android will immediately display a start window, which will stay around until your application is fully loaded, initialized, and can draw its first frame. This behavior is most often seen when your app is booted for the first time, but it can easily happen other times as well,like when the activity is brought to the foreground, or after the user backs out of your app, or after some portion of your app has been purged by the system to save memory.
Basically, any time the user moves from something else to your application, there’s a chance you can see this type of behavior. The important point here is this. Letting the user spend too much time looking at the start window gives them ample opportunity to get bored and move on to other things.And taking too long in general could even cause the Application Not Responding dialog to pop up.Neither of these are very good for user retention.
So from the technical side, the whole process works something like this. When the user launches your app, the system does a bit of work to load your application information and create a unique process for your app. From there, the system process will display the starting window and basically hang out until the application is up and running. Meanwhile, the application process will create the application object and launch the main thread. This is where your startup activity will be initialized, created, inflated, and finally drawn. It’s only at this point, after the application has drawn its first frame, that the system process then goes and swaps out the start window for the application.
Now, to be clear, the majority of that entire process happens pretty cleanly. There’s not really much chance that performance can go off the rails. However, there are three big areas where things could become problematic that you should keep an eye on.
The first thing you should really take a look at is all the work that goes into creating your activity class.Most often, there’s lots of heavy lifting that occurs during this process, but heaviest has to be the inflation of layouts and loading of resources that goes along with it.This is not a cheap process, and if you layouts are too complex or you’re got some blocking logic in there, this can cause some really big problems.
On a similar note, make sure you take a look at your application initialization. For really complex apps, the initialization of the app object often becomes a junk drawer for lots of global classes that might be used between activities.So there tends to be lots of work here that could be deferred to later times or perhaps loaded in a lazy-load fashion.
Now, there’s lots of applications out there which provide custom start windows. This is either done to help brand the application or to make a slow load look like a custom-branded application.Now, if you’re doing this to hide bad load times, obviously, you should fix that first. But if you’re doing it for branding, then you need to be aware that there’s a right and a wrong way to set this up, so that it doesn’t influence the user perception too negatively.
But before you run off into the weeds and try to fix these types of common patterns, you need to sit down and figure out if you have a problem in the first place. Thankfully, Android has a few tools to help.
Firstly is Displayed Time. For releases after KitKat, Logcat will include an output line which displays the amount of time between when the process was launched and the activity finally drawn to the screen. This can be helpful, because it gives you a general idea how long it takes to occur for your application. Oh, by the way, note, if you want to see this value inside of Android Studio, you need to turn off filters for the Logcat output. So keep that in mind.
Secondly is reportFullyDrawn function. The displayed metric that’s reported in Logcat is useful most situations where you’d like to track down the time it takes to go from application start to first visible. However, in modern application development, there’s often a great deal of lazy loading-that is, rather than blocking the initial drawing of the window, asynchronously loading resources and views in the background and updating the view hierarchy accordingly. The result is that while the initial activity may be visible,it may not yet be fully loaded with respect to resources, which could be considered a separate metric to use when evaluating launch time performance.To address this concern, you can manually call the activity.reportFullyDrawn function to let the system know that your activity is finished with its lazy loading.
Third is method tracing. While display time and reportFullyDrawn give a good understanding of the overall load time of your application, they do not provide details into what may be causing particular parts of that pipeline to go longer than expected. To gain more insight in this area, you can use the start method tracing tool inside of Android Studio.
And finally is the big one, Systrace. When you add trace functions inside of your onCreate methods, it will augment your logging, such that the Systrace tool can properly discover all the subsections and display them in its graphing process.