App 启动模式分以下 三 类 :
冷启动
热启动
温热启动
1.冷启动
APP
从零开始,APP
启动之前,系统没有为此 APP
创建独立进程。比如:设备启动后,APP
第一次Launch
或者APP
被Kill
掉后的重启。这种类型的启动优化存在很大挑战,因为Android
系统或应用还有其他更多的后台进程在运行。
启动流程大致如下:
点击Launcher 上的 icon开加载app
-->立即显示白屏或黑屏等
--> Application onCreate
--> Activity Init
----> Activity onCreate
—> 初始化数据,填充显示View
—> Activity onResume
等,详细请看下图:
App启动进程优化
2. 热启动
APP
的热启动要比 冷启动简单得多,内存开销也更低。APP
热启动时候,所有的系统都是把你的Activity
带到前台。如果APP
的所有Activity
仍驻留在内存中,则APP
可以避免重复对象初始化、布局绘制和显示等工作。
如果APP
在内存中被清理掉,比如调用ontrimmemory()
,当响应热启动时,这些对象将重新被创建。
热启动与冷启动相同的屏幕行为:
系统进程会显示一个空白屏幕,直到应用程序完成渲染后将此空白屏幕移除掉,此屏幕创建会在加载APP
时候立即创建,如需查看创建流程,需要查看PhoneWindosManger
中AddWindows
方法。
3. 温热启动
处于冷启动与热启动之间,既包含一些冷启动的操作,又含有部分热启动的功能。例如以下两种状态:
1. 用户退出APP
后重新Launch
。
此时此APP
的进程可能会存在,然鹅,Activity
必须重新创建并调用onCreate
方法
2. APP 被缓存中清理掉时。
此时用户重新Launch APP
时,此APP
的进程和Activity
都需要重新创建,但是任务栈中会保存部分APP
实例数据(bundle类型
)传递个Activity onCreate
方法
二、App 启动时间测量与分析
===============
为了更加准确的测量 APP
启动的耗时,请务必使用User
版本进行验证。UserDebug
或者eng
版本会开很多调试开关影响测试的正常结果。
如何获取APP
启动时间,请看以下测量方法
ps:以下测试方法请在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启动性能的方法,使用工具分析
三、应用中冷启动避免白屏、黑屏方案
=================
手机中 APP
首次启动(未在最近任务列表中,或已经运行过,但在最近任务列表中已清除启动记录)称为冷启动,此时打开APP
时候回闪白屏或黑屏,特别是当系统主题为黑色或白色时候比较明显。
在应用端规避掉打开APP
闪白屏、黑屏问题,主要是从android:windowIsTranslucent
上让白屏变透明,进而不让用户看到白屏、黑屏现象。
但是,此解决方案会导致在Launcher
中点击APP`` icon
是会有轻微的卡顿现象,此现象会让用户误认为手机卡,APP
启动慢,从而将打开APP
闪白屏的黑锅甩给手机制造厂商。
1. 透明样式Theme 解决方案如下:
1. 自定义透明样式
在res/values/style.xml
中自定义样式
自定义透明样式
2. App 启动入口Activity 中使用自定义样式
App 启动入口Activity 中使用自定义样式
注意: windowDisablePreview =false
属性可以不让白屏显示,失去中间白屏过度,会给用户带来不是太好的体验,比如点击后需要稍微等一下才会打开APP
,会让用户错误的怀疑自己是否成功点击过icon。Google 很不推荐此种做法。
2. 使用app logo等图片样式使用方法如下
1. 自定义Theme
自定义Theme
2. 为 要启动的Activity设置自定义样式
为 要启动的Activity设置自定义样式
3. 同样也可以在Java类中的 设置样式
Java类中的 设置样式
此方法也是Google
推荐的方法,建议大家可以用自定义Theme
替换掉系统中的白屏,当然也可以搞成什么广告页面等等。
四、 Framework 层解决冷启动白屏、黑屏方案
==========================
打开APP
闪黑屏、白屏的根本原因在于PhonewindowManger
中的addStartingWindow
方法。
addStartingWindow方法
自定义填充Window 背景
Framwork
上 这样修改后,会将白色屏幕替换成我们客制化的颜色,此修改会影响到所有APP
的启动。
五、App 启动优化原理
============
L
版本之后,手机上所有APP
都要经过dex2oat
处理之后,才能运行.
dex2oat
是将原来的dex文件预先的翻译处理,从而加快APP
运行的时间,但由于某些APP
比较复杂,优化的时间可能会比较长,进而给用户感觉运行卡顿。
dex2oat
优化是以dex
文件中的method
为单位,dex2oat
会根据需要优化一定量的method,也就是说并不是优化的method
都会被翻译成oat
模式。
实战系列
话不多说,Android实战系列集合都已经系统分类好,由于文章篇幅问题没法过多展示
===
L
版本之后,手机上所有APP
都要经过dex2oat
处理之后,才能运行.
dex2oat
是将原来的dex文件预先的翻译处理,从而加快APP
运行的时间,但由于某些APP
比较复杂,优化的时间可能会比较长,进而给用户感觉运行卡顿。
dex2oat
优化是以dex
文件中的method
为单位,dex2oat
会根据需要优化一定量的method,也就是说并不是优化的method
都会被翻译成oat
模式。
实战系列
话不多说,Android实战系列集合都已经系统分类好,由于文章篇幅问题没法过多展示
[外链图片转存中…(img-rsaRWABX-1719804535628)]
[外链图片转存中…(img-dAUTRyfs-1719804535628)]