如果发现显示时间比希望的时间长,则可以继续尝试识别启动过程中的瓶颈。查找瓶颈的一个好方法是使用Android Studio CPU性能剖析器。

Traceview是android平台配备一个很好的性能分析的工具。它可以通过图形化的方式让我们了解我们要跟踪的程序的性能,并且能具体到每个方法的执行时间。但是目前Traceview已弃用。如果使用Android
Studio3.2或更高版本,则应改为使用CPU Profiler

要在应用启动过程中自动开始记录CPU活动,请执行以下操作:

1.依次选择Run>EditConfigurations。

android cpu占用 shell android cpu profile_java


2.在 Profiling 标签中,勾选 Start recording CPU activity on startup 旁边的复选框。

android cpu占用 shell android cpu profile_java_02


3.从菜单中选择 CPU 记录配置。

Sample Java Methods

对 Java 方法采样:在应用的 Java 代码执行期间,频繁捕获应用的调用堆栈。分析器会比较捕获的数据集, 以推导与应用的 Java 代码执行有关的时间和资源使用信息。如果应用在捕获调用堆栈后进入一个方法并在下次捕获前退出该方法,分析器将不会记录该方法调用。如果您想要跟踪生命周期如此短的方法,应使用检测 跟踪。

Trace Java Methods

跟踪 Java 方法:在运行时检测应用,以在每个方法调用开始和结束时记录一个时间戳。系统会收集并比较这些时间戳,以生成方法跟踪数据,包括时间信息和 CPU 使用率。

Sample C/C++ Functions

对 C/C++ 函数采样:捕获应用的原生线程的采样跟踪数据。要使用此配置,您必须将应用部署到搭载

Android 8.0(API 级别 26)或更高版本的设备上。

Trace System Calls

跟踪系统调用:捕获非常翔实的细节,以便您检查应用与系统资源的交互情况。您可以检查线程状态的确切 时间和持续时间、直观地查看所有内核的 CPU 瓶颈在何处,并添加要分析的自定义跟踪事件。要使用此配置,您必须将应用部署到搭载 Android 7.0(API 级别 24)或更高版本的设备上。

此跟踪配置在 systrace 的基础上构建而成。您可以使用 systrace 命令行实用程序指定除 CPU Profiler 提供的选项之外的其他选项。systrace 提供的其他系统级数据可帮助您检查原生系统进程并排查丢帧或帧延迟问题。

4.点击 Apply。

5.依次选择 Run > Profile,将您的应用部署到搭载 Android 8.0(API 级别 26)或更高版本的设备上。

android cpu占用 shell android cpu profile_android_03


点击Stop,结束跟踪后显示:

android cpu占用 shell android cpu profile_java_04

Call Chart

以图形来呈现方法跟踪数据或函数跟踪数据,其中调用的时间段和时间在横轴上表示,而其被调用方则在纵轴上显 示。对系统 API 的调用显示为橙色,对应用自有方法的调用显示为绿色,对第三方 API(包括 Java 语言 API)的调用显示为蓝色。

android cpu占用 shell android cpu profile_android cpu占用 shell_05


android cpu占用 shell android cpu profile_android_06

如上图,自定义ApplicationonCreate 调用了Thread.sleep 耗时为:3s。
Call Chart 已经比原数据可读性高很多,但它仍然不方便发现那些运行时间很长的代码,这时我们便需要使用Flame Chart

Flame Chart

提供一个倒置的调用图表,用来汇总完全相同的调用堆栈。也就是说,将具有相同调用方顺序的完全相同的方法或 函数收集起来,并在火焰图中将它们表示为一个较长的横条 。横轴显示的是百分比数值。由于忽略了时间线信息,Flame Chart 可以展示每次调用消耗时间占用整个记录时长的百分比。 同时纵轴也被对调了,在顶部展示的是被调用者,底部展示的是调用者。此时的图表看起来越往上越窄, 就好像火焰一样,因此得名: 火焰图。

说白了就是将Call Chart上下调用栈倒过来。

android cpu占用 shell android cpu profile_android studio_07


android cpu占用 shell android cpu profile_android_08


耗时最长的为:Thread.sleep

Top Down Tree

如果我们需要更精确的时间信息,就需要使用 Top Down Tree。 Top Down Tree显示一个调用列表,在该列表中展开方法或函数节点会显示它调用了的方法节点。

android cpu占用 shell android cpu profile_android cpu占用 shell_09


android cpu占用 shell android cpu profile_android_10


对于每个节点,三个时间信息:

  • Self Time —— 运行自己的代码所消耗的时间;
  • Children Time —— 调用其他方法的时间;
  • Total Time —— 前面两者时间之和。

此视图能够非常方便看到耗时最长的方法调用

Bottom Up Tree

方便地找到某个方法的调用栈。在该列表中展开方法或函数节点会显示哪个方法调用了自己。

android cpu占用 shell android cpu profile_API_11


通过工具可以定位到耗时代码,然后查看是否可以进行优化。对于APP启动来说,启动耗时包括Android系统启动APP进程加上APP启动界面的耗时时长,我们可做的优化是APP启动界面的耗时,也就是说从Application的构建到主界面的onWindowFocusChange的这一段时间。

因此在这段时间内,我们的代码需要尽量避免耗时操作,检查的方向包括:主线程IO;第三方库初始化或程序需要 使用的数据等初始化改为异步加载/懒加载;减少布局复杂度与嵌套层级;Multidex(5.0以上无需考虑)等。

Debug API

除了直接使用 Profile 启动之外,我们还可以借助Debug API生成trace文件。

android cpu占用 shell android cpu profile_android studio_12


运行App,则会在sdcard中生成一个enjoy.trace文件(需要sdcard读写权限)。将手机中的trace文件保存至电脑,随后拖入Android Studio即可。