这多是最好的性能优化教程(二)

前言

上篇写了 ArrayMap 和 UI 性能优化,这篇我想和你们聊聊每一个人都关心的 APP 启动,参见 Android 性能优化典范android

正文

提升 APP 的启动速度对咱们意义深远,很显然,APP 的启动时间越短,使用它的用户越有耐心等待打开这个 APP 进行使用。反之,启动时间太长,用户则有可能还没等到 APP 打开就已经切换到其余 APP 了。性能优化

程序启动过程当中那些复杂错误的操做颇有可能致使严重的性能问题。Android 系统会根据用户的操做行为调整程序的显示策略,用来提升程序的显示性能。例如,一旦用户点击桌面图标,Android 系统会当即显示一个启动窗口,这个窗口会一直保持显示直到画面中的元素成功加载并绘制完第一帧。这种行为常见于程序的冷启动,或者程序的热启动场景(程序从后台被唤起或者从其余 APP 界面切换回来)。网络

那么关键的问题是,用户极可能会由于从启动窗口到显示画面的过程耗时过长而感到厌烦,从而致使用户没有来得及等程序启动完毕就切换到其余 APP 了。更严重的是,若是启动时间过长,可能致使程序出现 ANR。咱们应该避免出现这两种糟糕的状况异步

从技术角度来讲,当用户点击桌面图标开始,系统会当即为这个 APP 建立独立的专属进程,而后显示启动窗口,直到 APP 在本身的进程里面完成了程序的建立以及主线程完成了 Activity 的初始化显示操做,再而后系统进程就会把启动窗口替换成 APP 的显示窗口。函数

上述流程里面的绝大多数步骤都是由系统控制的,通常来讲不会出现什么问题,但是对于启动速度,咱们可以控制而且须要特别关注的地方主要有三处:工具

  • Activity 的 onCreate 流程,特别是UI的布局与渲染操做,若是布局过于复杂极可能致使严重的启动性能问题。
  • Application 的 onCreate 流程,对于大型的 APP 来讲,一般会在这里作大量的通用组件的初始化操做。
  • 目前有部分 APP 会提供自定义的启动窗口,这里能够作成品牌宣传界面或者是给用户提供一种程序已经启动的视觉效果。

在正式着手解决问题以前,咱们须要掌握一套正确测量评估启动性能的方法。所幸的是,Android 系统有提供一些工具来帮助咱们定位问题。布局

有趣的启动时长定位

display time

从 Android KitKat 版本开始,Logcat 中会输出从程序启动到某个 Activity 显示到画面上所花费的时间。这个方法比较适合测量程序的启动时间。
性能

reportFullyDrawn()

咱们一般来讲会使用异步懒加载的方式来提高程序画面的显示速度,这一般会致使的一个问题是,程序画面已经显示,但是内容却还在加载中。为了衡量这些异步加载资源所耗费的时间,咱们能够在异步加载完毕以后调用 activity.reportFullyDrawn() 方法来告诉系统此时的状态,以便获取整个加载的耗时。
优化

Method Tracing

前面两个方法提供了启动耗时的总时间,但是却没法提供具体的耗时细节。为了获取具体的耗时分布状况,咱们可使用 Method Tracing 工具来进行详细的测量。spa

Systrace

咱们能够在 onCreate() 方法里面添加 trace.beginSection()trace.endSection() 方法来声明须要跟踪的起止位置,系统会帮忙统计中间经历过的函数调用耗时,并输出报表。

若是优化 APP 启动速度?

提高 Activity 的建立速度

提高 Activity 的建立速度是优化 APP 启动速度的首要关注目标。从桌面点击 APP 图标启动应用开始,程序会显示一个启动窗口等待 Activity 的建立加载完毕再进行显示。在 Activity 的建立加载过程当中,会执行不少的操做,例如设置页面的主题,初始化页面的布局,加载图片,获取网络数据,读写 Preference 等等。


上述操做的任何一个环节出现性能问题均可能致使画面不能及时显示,影响了程序的启动速度。上一个段落咱们介绍了使用 Method Tracing 来发现那些耗时占比相对较多的方法。假设咱们发现某个方法执行时间过长,接下去就可使用 Systrace 来帮忙定位究竟是什么缘由致使那个方法执行时间过长。

除了使用工具进行具体定位分析性能问题以外,如下两点经验能够帮助咱们对 Activity 启动作性能优化:

  • 优化布局耗时:一个布局层级越深,里面包含须要加载的元素越多,就会耗费更多的初始化时间。关于布局性能的优化,这里就不展开描述了!
  • 异步延迟加载:一开始只初始化最须要的布局,异步加载图片,非当即须要的组件能够作延迟加载。

别让 Application 初始化没必要要的东西

在 Application 初始化的地方作太多繁重的事情是可能致使严重启动性能问题的元凶之一。Application 里面的初始化操做不结束,其余任意的程序操做都没法进行。

有时候,咱们会一股脑的把绝大多数全局组件的初始化操做都放在 Application 的 onCreate() 里面,但其实不少组件是须要作区队对待的,有些能够作延迟加载,有些能够放到其余的地方作初始化操做,特别须要留意包含 Disk IO 操做,网络访问等严重耗时的任务,他们会严重阻塞程序的启动。


优化这些问题的解决方案是作延迟加载,能够在 Application 里面作延迟加载,也能够把一些初始化的操做延迟到组件真正被调用到的时候再作加载。

恰当地使用闪屏

启动闪屏不只仅能够做为品牌宣传页,还可以减轻用户对启动耗时的感知,可是若是使用不恰当,将拔苗助长。前面介绍过当点击桌面图标启动 APP 的时候,程序会显示一个启动窗口,一直到页面的渲染加载完毕。若是程序的启动速度足够快,咱们看的闪屏窗口停留显示的时间则会很短,可是当程序启动速度偏慢的时候,这个启动闪屏能够必定程度上减轻用户等待的焦虑感,避免用户过于轻易的关闭应用。

目前大多数开发者都会经过设置启动窗口主题的方式来替换系统默认的启动窗口,经过这种方式只是使用『障眼法』弱化了用户对启动时间的感知,但本质上并无对启动速度作什么优化。也有些 APP 经过关闭启动窗口属性 android:windowDisablePreview 的方式来直接移除系统默认的启动窗口,可是这样的弊端是用户从点击桌面图标到真的看到实际页面的这段时间当中,画面没有任何变化,这样的用户体验是十分糟糕的!

对于启动闪屏,正确的使用方法是自定义一张图片,把这张图片经过设置主题的方式显示为启动闪屏,代码执行到主页面的 onCreate() 的时候设置为程序正常的主题。

后记

本篇咱们根据胡凯老师总结,解决了启动速度响应,下期咱们将带来内存管理章节。
若是想第一时间收到更新信息的能够关注个人简书:简书地址
你也能够选择关注个人公众号:nanchen

相关文章
相关标签/搜索