App 启动时间优化

《App 启动时间优化》
《App 启动时间优化》

极力推荐Android 开发大总结文章:欢迎收藏
程序员Android 力荐 ,Android 开发者需要的必备技能

《App 启动时间优化》

用户希望
APP能够快速响应并加载。 一个启动速度慢的
APP 不符合用户期望,可能会令用户失望,并且可能会导致用户对您的应用程序评价不佳,甚至会卸载你的应用。

本文将讨论如何优化应用的启动时间,首先我们需要了解APP启动的相关内容。

通过本篇文章,您将学习到以下内容

  1. App 启动模式分类
  2. 应用中冷启动避免白屏、黑屏方案
  3. Framework 层解决冷启动白屏、黑屏方案
  4. App 启动优化原理
  5. App 启动优化简介
  6. App 启动优化方案
  7. 在 PMS中 App 启动优化方案

1. App 启动模式分类

App 启动模式分以下 三 类 :

1.冷启动
2.热启动
3.温热启动

  • 1.冷启动

APP从零开始,APP启动之前,系统没有为此 APP创建独立进程。比如:设备启动后,APP第一次Launch或者APPKill掉后的重启。这种类型的启动优化存在很大挑战,因为Android系统或应用还有其他更多的后台进程在运行。

启动流程大致如下:

点击Launcher 上的 icon开加载app –>立即显示白屏或黑屏等 –> Application onCreate –> Activity Init—-> Activity onCreate —> 初始化数据,填充显示View —> Activity onResume等,详细请看下图:

《App 启动时间优化》 App启动进程优化

    1. 热启动

APP的热启动要比 冷启动简单得多,内存开销也更低。APP热启动时候,所有的系统都是把你的Activity带到前台。如果APP的所有Activity仍驻留在内存中,则APP可以避免重复对象初始化、布局绘制和显示等工作。
如果APP 在内存中被清理掉,比如调用ontrimmemory(),当响应热启动时,这些对象将重新被创建。

热启动与冷启动相同的屏幕行为:
系统进程会显示一个空白屏幕,直到应用程序完成渲染后将此空白屏幕移除掉,此屏幕创建会在加载APP时候立即创建,如需查看创建流程,需要查看PhoneWindosMangerAddWindows方法。

    1. 温热启动

处于冷启动与热启动之间,既包含一些冷启动的操作,又含有部分热启动的功能。例如以下两种状态:

  1. 用户退出APP后重新Launch

此时此APP的进程可能会存在,然鹅,Activity 必须重新创建并调用onCreate方法

  1. APP 被缓存中清理掉时。

此时用户重新Launch APP时,此APP的进程和Activity都需要重新创建,但是任务栈中会保存部分APP实例数据(bundle类型)传递个Activity onCreate方法

2. App 启动时间测量与分析

为了更加准确的测量 APP 启动的耗时,请务必使用User版本进行验证。UserDebug 或者eng版本会开很多调试开关影响测试的正常结果。

如何获取APP启动时间,请看以下测量方法

主要: 以下测试方法请在Android 4.4(含) 以上的版本进行

1.通过 adb 命令测量APP 冷启动时间

使用adb 命令直接启动APP进而测量APP启动耗时 的方法如下:

adb shell am start -W [packageName]/[packageName.MainActivity]


adb [-d|-e|-s <serialNumber>] shell am start -S -W [packageName]/[packageName.MainActivity] -c android.intent.category.LAUNCHER -a android.intent.action.MAIN
如要测量的app没有源码,比如:QQ,请用以下命令获取, 当前获取焦点的Activity ,方法信息如下:

adb shell dumpsys activity |findstr "mFocused"

APP 启动时间详情 请看以下图片中椭圆 红框区域内容。

《App 启动时间优化》 测量APP冷启动时间的方法

2.通过 adb logcat 查看APP 启动时间

Log中,主要是 通过分析 logcatAPPActivityManager: Displayed的时间值 ,此时间值包含以下时间综合信息:

  1. Launch 进程
  2. 初始化对象
  3. 创建并初始化Activity
  4. 填充布局
  5. 第一次绘制app 内容

比如下图:ProgramAndroid程序启动时间700ms

《App 启动时间优化》 adb logcat 查看APP 启动时间

3. 在代码中测量app启动性能的方法如下:

Activity代码用调用 reportFullyDrawn(); 方法,将绘制完成后信息反馈到Log上,此方法跟logcat中查看的时间相似。
比如自己运行ProgramAndrod APP的启动时间信息如下

11-24 11:47:00.363   982  1191 I ActivityManager: 
Fully drawn com.programandroid/.MainActivity: +998ms

《App 启动时间优化》 reportFullyDrawn()方法告知系统app Launch 成功时间

4. 使用Systrace 工具分析app启动时间

当然如果感觉上述方法比较麻烦,可以使用Systrace工具进行分析,工具分析情况,下次贴出。

《App 启动时间优化》 在代码中测量app启动性能的方法,使用工具分析

2. 应用中冷启动避免白屏、黑屏方案

手机中 APP首次启动(未在最近任务列表中,或已经运行过,但在最近任务列表中已清除启动记录)称为冷启动,此时打开APP时候回闪白屏或黑屏,特别是当系统主题为黑色或白色时候比较明显。

在应用端规避掉打开APP闪白屏、黑屏问题,主要是从android:windowIsTranslucent上让白屏变透明,进而不让用户看到白屏、黑屏现象。

但是,此解决方案会导致在Launcher中点击APP`` icon 是会有轻微的卡顿现象,此现象会让用户误认为手机卡,APP启动慢,从而将打开APP闪白屏的黑锅甩给手机制造厂商。

1. 透明样式Theme 解决方案如下:

    1. 自定义透明样式
      res/values/style.xml中自定义样式

《App 启动时间优化》 自定义透明样式

    1. App 启动入口Activity 中使用自定义样式

《App 启动时间优化》 App 启动入口Activity 中使用自定义样式

注意: windowDisablePreview =false 属性可以不让白屏显示,失去中间白屏过度,会给用户带来不是太好的体验,比如点击后需要稍微等一下才会打开APP,会让用户错误的怀疑自己是否成功点击过icon。Google 很不推荐此种做法。

2. 使用app logo等图片样式使用方法如下

  1. 自定义Theme

《App 启动时间优化》 自定义Theme

  1. 为 要启动的Activity设置自定义样式

《App 启动时间优化》 为 要启动的Activity设置自定义样式

  1. 同样也可以在Java类中的 设置样式

《App 启动时间优化》 Java类中的 设置样式

此方法也是Google推荐的方法,建议大家可以用自定义Theme替换掉系统中的白屏,当然也可以搞成什么广告页面等等。

3. Framework 层解决冷启动白屏、黑屏方案

打开APP闪黑屏、白屏的根本原因在于PhonewindowManger中的addStartingWindow 方法。

《App 启动时间优化》 addStartingWindow方法
《App 启动时间优化》 自定义填充Window 背景

Framwork上 这样修改后,会将白色屏幕替换成我们客制化的颜色,此修改会影响到所有APP的启动。

4. App 启动优化原理

L版本之后,手机上所有APP都要经过dex2oat处理之后,才能运行.
dex2oat 是将原来的dex文件预先的翻译处理,从而加快APP运行的时间,但由于某些APP比较复杂,优化的时间可能会比较长,进而给用户感觉运行卡顿。

dex2oat 优化是以dex文件中的method为单位,dex2oat 会根据需要优化一定量的method,也就是说并不是优化的method都会被翻译成oat模式。

根据优化的method的量的多少,可以分为如下的几种模式:

《App 启动时间优化》 Android 虚拟机优化模式

5. App 启动优化简介

Android L之后的版本,如无特殊处理,APP启动模式为Speed模式,此模式性能较好,但优化之后的文件占用空间比较大。不同模式可以看上面MTK 提供的参考标准。

APP的优化是通过dex2oat 去执行的,优化模式的参数是有外界调用dex2oat方法传递的参数控制,如无传递参数,默认参数Speed

那么调用dex2oat的路径有哪些呢?

  • 1.安装APP时

通过 Framework 下的PackageManagerService 将参数传递给 mAppInstallDir,然后mAppInstallDir 调用dex2oat,因此此种方式的优化模式通过PMS控制。

此种模式是将APP的路径,优化之后的oat存放路径,传递给dex2oat
但是由于内容可能发生改变,我们有可能无法在dex2oatAPP加以识别,所以,这时候,可以在installd或者PMS中加以判断,是否是我们认为安装比较慢的APP,如果是的话,则改变其优化模式。

    1. APP自身优化插件时

此种模式往往会指定模式为speed模式或者不指定,在优化之后的保存路径中,携带APP的包名。

《App 启动时间优化》 intall.jpg

目前有些 apkFacebook、微信WeChatAPP,应用本身较大且代码复杂度高,可能会出现安装失败,安装慢等问题。

安装失败是由于dex2oat进程编译时间过久打到了timeout
安装慢当然就是dex2oat做的compiler久的原因。

另外,像 微信 WeChat 这种apk在启动应用的时候是会优化插件的(而不是在安装的时候优化),这样就会导致应用lunch时间过久,给用户的感觉就是很晚才入,手机卡顿等锅,让手机厂商背负。在需更改优化的模式,加快安装的时间时,请注意此修改会降低 APP 运行的性能。

注意:
APP安装 / lunch时间的长短取决于CPU核心数,8 核CPU 肯定比 4 核 CPU优化要快,除此之外,还取决于EMMC的性能 ,memory等系统因素。

6. App 启动优化方案

对于APP优化目前有3个地方可以进行处理。

    1. PackageManagerService中

这个地方是安装APP必经之路,代码存放地址如下:

《App 启动时间优化》 PackageManagerService 代码路径

    1. installd的commands.cpp中

这也是安装APP的必经之路 ,代码存放地址如下:

《App 启动时间优化》 commands.cpp代码存放路径

    1. dex2oat 中

ex2oat是所有APP或者jar包的必经之路,但是由于传递给dex2oat的参数有限,所以可能无法识别。

因此,对于安装APP可以在PMS中修改,而对于jar包可以在dex2oat当中修改。
因为PMS中我们可以知道APPpkg信息,这个是每一个APP唯一的。
而对jar包来说,由于每一个APP在优化的时候,喜欢把优化之后的jar包放在自己安装的APP路径下面。所以,可以利用这个特性进行判断 。

7. 在 PMS中 App 启动优化方案

此解决方案适用于Android N版本

主要修改PackageDexOptimizer.java文件的 performDexOptLI方法中进行优化。

《App 启动时间优化》 image.png

在这函数中,可以判断传递下来的pkg是否是我们需要的APP,如果是的话,将targetCompilerFilter设置为speed-profile
speed-profile 会在安装的时候采用 interperter-only,然后,运行一段时间之后,会将那些常用的方法优化成为speed模式。也就是说是有选择性的优化。

《App 启动时间优化》 优化 app 启动模式
《App 启动时间优化》 查看 APP 启动模式
《App 启动时间优化》
《App 启动时间优化》

至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

《App 启动时间优化》

如有侵权,请联系小编,小编对此深感抱歉,届时小编会删除文章,立即停止侵权行为,请您多多包涵。

《App 启动时间优化》

既然都看到这里,领两个红包在走吧!
以下两个红包每天都可以领取

1.支付宝搜索 522398497,或扫码支付宝红包海报。

《App 启动时间优化》 支付宝扫一扫,每天领取大红包

2.微信红包,微信扫一扫即可领取红包

《App 启动时间优化》 微信扫一扫,每天领取微信红包

    原文作者:ProgramAndroid
    原文地址: https://www.jianshu.com/p/4f5c5f7d4173
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞