一、背景
在开发过程中,发现每次点击桌面app图标之后,都有一个在明显的桌面等待时间,机型越低端的越明显,因此考虑进行优化解决。
[图片太大]
从图1中可以看到,在图标按钮被按下后,明显在延迟了1-2s后应用才给出反应;而图2在点击后则直接有了应用反应,完全达到了秒开应用的效果。
二、冷启动过程
要做优化首先就要了解应用冷启动的过程:
有兴趣的同学可以研究下细节,简单的概述冷启动过程可以如下:
Zygote Fork Proccess
-> Application:attachBaseContext()
-> Application:onCreate()
-> MainActiviity:onCreate()
多歧路,今犹在
了解了冷启动的过程,问题看上去就似乎变得很简单了,我只要把这个几个函数优化好、做好同步异步操作、减少函数耗时是不是就可以达到秒开了? #哇塞!好机智的样纸#
不得不说,这真是一个坑。
关于冷启动的优化,其实主要集中在上述的几个生命周期函数中,我们也做了大量的工作去研究关于生命周期函数内的优化,在一方面我们必须承认冷启动的优化的确是很有意义和必须的
但是,我们也最终认识到,应用秒开 和 冷启动优化真的关系不大 [捂脸][捂脸]
三、Window Background
在AndroidDeveloper的Launch-Time Performance有这么一句话:
当打开一个Activity时,如果这个Activity所属Application还没有在运行,系统会为这个Activity的创建一个进程(每开启一个进程都会有一个Application,所以Application的onCreate()可能会被调用多次),但进程的创建与初始化都需要时间,在这个动作完成之前,如果初始化的时间过长,屏幕上可能没有任何动静,用户会以为没有点到按钮。
所以既不能停在原来的地方又没到显示新的界面,怎么办呢?这就有了StartingWindow(也称之为PreviewWindow)的出现,这样看起来就像Activity已经启动起来了,只是数据内容还没有初始化好。
StartingWindow一般出现在应用程序进程创建并初始化成功前,所以它是个临时窗口,对应的WindowType是TYPE_APPLICATION_STARTING。目的是告诉用户,系统已经接受到操作,正在响应,在程序初始化完成后实现目的UI,同时移除这个窗口.
一般情况下我们会对Application和Activity设置Theme,系统会根据设置的Theme初始化StartingWindow。Window布局的顶层是DecorView,StartingWindow显示一个空DecorView,但是会给这个DecorView应用这个Activity指定的Theme,如果这个Activity没有指定Theme就用Application的(Application系统要求必须设置Theme)
在Theme中可以指定窗口的背景,Activity的ICON,APP整体文字颜色等,如果说没有指定任何属性,就会用默认的属性,也就是上文中提到的空DecorView.
3.1 APP启动时白屏/黑屏、Activity打开时白屏/黑屏
口袋助理在之前为了解决“APP启动时白屏/黑屏、Activity打开时白屏/黑屏”为应用设置了透明背景。
<style name="xx" parent="AppTheme">
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsTranslucent">true</item>
</style>
设置后,用户点击我们APP图标后,需要等待2秒左右的时候才会显示contentView。造成了APP启动速度慢的假象,其实Activity已经启动了,只是background是透明的,这时候你点击桌面的其他地方是无效的
3.2 秒开方案
思路:我们之前设置了Window透明,实现了去掉白屏和黑屏,完全可以为MainActivity设置一个log样式的Window Background 从而实现秒开
3.2.1 设置自定义带windowBackground的Theme
<item name="android:windowBackground">@drawable/splash</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowNoTitle">true</item>
<!-- <item name="android:windowIsTranslucent">true</item> --> <!-- 透明背景不要了 -->
前两行代码是设置Theme不透明并且默认渲染的背景图是我们必看闪屏页的图片。
windowBackground:关键,主要设置你想要的背景图或者是动态自绘的drawable皆行,这个视图会在你冷启动时渲染给用户过渡看。
windowFullscreen:全屏展示,免得顶部状态栏显现颜色不一致过于脱节和突兀