您的位置:首页 > 移动开发

App 启动时间优化方法详解

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

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

App 启动模式分类
应用中冷启动避免白屏、黑屏方案
Framework 层解决冷启动白屏、黑屏方案
App 启动优化原理
App 启动优化简介
App 启动优化方案
在 PMS中 App 启动优化方案

欢迎关注微信公众号:程序员Android

公众号ID:ProgramAndroid

获取更多信息



微信公众号:ProgramAndroid

我们不是牛逼的程序员,我们只是程序开发中的垫脚石。

我们不发送红包,我们只是红包的搬运工。


1. App 启动模式分类

App 启动模式分以下 三 类 :

1.冷启动

2.热启动

3.温热启动

1.冷启动
app 从零开始,APP 启动之前,系统没有为此 app 创建独立进程。比如:设备启动后,app第一次 Launch 或者app被Kill 掉后的重启。这种类型的启动优化存在很大挑战,因为Android 系统或应用还有其他更多的后台进程在运行。
启动流程大致如下:
点击Launcher
上的 icon开加载app
 -->
立即显示白屏或黑屏等
 --> 
Application
onCreate
 --> 
Activity Init
----> 
Activity
onCreate
 ---> 
初始化数据,填充显示View
 ---> 
Activity
onResume
等,详细请看下图:



App启动进程优化

热启动

APP 的热启动要比 冷启动简单得多,内存开销也更低。APP热启动时候,所有的系统都是把你的
Activity
带到前台。如果APP的所有Activity
仍驻留在内存中,则APP 可以避免重复对象初始化、布局绘制和显示等工作。

如果APP 在内存中被清理掉,比如调用
ontrimmemory()
,当响应热启动时,这些对象将重新被创建。
热启动与冷启动相同的屏幕行为:

系统进程会显示一个空白屏幕,直到应用程序完成渲染后将此空白屏幕移除掉,此屏幕创建会在加载app时候立即创建,如需查看创建流程,需要查看
PhoneWindosManger
AddWindows
方法。

温热启动

处于冷启动与热启动之间,既包含一些冷启动的操作,又含有部分热启动的功能。例如以下两种状态:
用户退出APP后重新Launch。
此时此APP的进程可能会存在,然鹅,Activity 必须重新创建并调用
onCreate
方法
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冷启动时间的方法


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

在Log中,主要是 通过分析 logcat中app 在 
ActivityManager:
Displayed
的时间值 ,此时间值包含以下时间综合信息:
Launch 进程
初始化对象
创建并初始化Activity
填充布局
第一次绘制app 内容
比如下图:ProgramAndroid程序启动时间 700ms



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




reportFullyDrawn()方法告知系统app Launch 成功时间


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

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



在代码中测量app启动性能的方法,使用工具分析


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

手机中 App 首次启动(未在最近任务列表中,或已经运行过,但在最近任务列表中已清除启动记录)称为冷启动,此时打开app时候回闪白屏或黑屏,特别是当系统主题为黑色或白色时候比较明显。
在应用端规避掉打开app 闪白屏、黑屏问题,主要是从
android:windowIsTranslucent
上让白屏变透明,进而不让用户看到白屏、黑屏现象。
但是,此解决方案会导致在Launcher 中点击app icon 是会有轻微的卡顿现象,此现象会让用户误认为手机卡,app启动慢,从而将打开app 闪白屏的黑锅甩给手机制造厂商。


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

自定义透明样式

在res/values/style.xml 中自定义样式



自定义透明样式

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



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

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


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

自定义Theme
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@android:color/white"/>
<!-- Your product logo - 144dp color version of your app icon -->
<item>
<bitmap
android:src="@drawable/product_logo_144dp"
android:gravity="center"/>
</item>
</layer-list>

为 要启动的Activity设置自定义样式
<activity ...
android:theme="@style/AppTheme.Launcher" />

同样也可以在Java类中的 设置样式
public class MyMainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Make sure this is before calling super.onCreate
setTheme(R.style.Theme_MyApp);
super.onCreate(savedInstanceState);
// ...
}
}

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


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

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



addStartingWindow方法



自定义填充Window 背景

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


4. App 启动优化原理

L版本之后,手机上所有APP都要经过
dex2oat
处理之后,才能运行.
dex2oat
 是将原来的dex文件预先的翻译处理,从而加快APP运行的时间,但由于某些APP比较复杂,优化的时间可能会比较长,进而给用户感觉运行卡顿。
dex2oat
 优化是以dex文件中的
method
为单位,
dex2oat
 会根据需要优化一定量的method,也就是说并不是优化的
method
都会被翻译成
oat
模式。
根据优化的
method
的量的多少,可以分为如下的几种模式:



Android 虚拟机优化模式


5. App 启动优化简介

Android L之后的版本,如无特殊处理,app启动模式为
Speed
模式,此模式性能较好,但优化之后的文件占用空间比较大。不同模式可以看上面MTK
提供的参考标准。
对App 的优化是通过
dex2oat
 去执行的,优化模式的参数是有外界调用
dex2oat
方法传递的参数控制,如无传递参数,默认参数
Speed

那么调用
dex2oat
的路径有哪些呢?
1.安装APP时
通过 Framework 下的
PackageManagerService
 将参数传递给 
mAppInstallDir
,然后
mAppInstallDir
 调用
dex2oat
,因此此种方式的优化模式通过PMS控制。
此种模式是将
APP
的路径,优化之后的
oat
存放路径,传递给
dex2oat


但是由于内容可能发生改变,我们有可能无法在
dex2oat
APP
加以识别,所以,这时候,可以在
installd
或者
PMS
中加以判断,是否是我们认为安装比较慢的APP,如果是的话,则改变其优化模式。

APP自身优化插件时

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



intall.jpg

目前有些 apk 像 Facebook、微信 WeChat 等 apk,应用本身较大且代码复杂度高,可能会出现安装失败,安装慢等问题。
安装失败是由于dex2oat进程编译时间过久打到了
timeout


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

注意:

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


6. App 启动优化方案

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

PackageManagerService中

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



PackageManagerService 代码路径

installd的commands.cpp中

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



commands.cpp代码存放路径

dex2oat 中

ex2oat是所有APP或者jar包的必经之路,但是由于传递给dex2oat的参数有限,所以可能无法识别。
因此,对于安装APP可以在PMS中修改,而对于jar包可以在dex2oat当中修改。

因为PMS中我们可以知道APP的
pkg
信息,这个是每一个APP唯一的。

而对jar包来说,由于每一个APP在优化的时候,喜欢把优化之后的jar包放在自己安装的APP路径下面。所以,可以利用这个特性进行判断 。


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

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

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



image.png

在这函数中,可以判断传递下来的
pkg
是否是我们需要的app,如果是的话,将
targetCompilerFilter
设置为
speed-profile

speed-profile
 会在安装的时候采用 
interperter-only
,然后,运行一段时间之后,会将那些常用的方法优化成为
speed
模式。也就是说是有选择性的优化。



优化 app 启动模式



查看 APP 启动模式

​欢迎关注微信公众号:程序员Android

公众号ID:ProgramAndroid

获取更多信息



微信公众号:ProgramAndroid

我们不是牛逼的程序员,我们只是程序开发中的垫脚石。

我们不发送红包,我们只是红包的搬运工。



点击阅读原文,获取更多福利

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: