Android App的启动黑/白屏
作为一名Android应用开发者,都会遇到过打开应用会出现短暂黑/白屏,之后才会出现正常的应用界面;然而又有很多APP,好像可以秒开而无黑/白屏的问题,如淘宝/美团/微信…..
Splash Activity
任何一个Android应用,都会在AndroidManifest.xml中,声明一个App启动时的Launcher Activity,绝大部分应用都会使用Splash Activity作为这个启动的界面。
如果按照正常的逻辑编写代码,大部分童鞋一定会把这个SplashActivity的内容设置为铺满一张高清的静态图或几张引导页等等。
这时候,就会出现上诉情况,十分影响用户体验,建议还在这么写的童鞋们,看看本文是如何解决的。
Activity如何被打开
我们在使用Activity的过程中,往往只看重它要显示的内容,而却忽略了其复杂的启动过程,就黑/白屏的根本原因不就是我们在Activity的onCreate(...)
方法中通过setContentView(View)
设置的布局并没有被立即绘制到窗口上。
当打开一个Activity时,如果这个Activity所属Application还没有在运行,系统会为这个Activity的创建一个进程(每开启一个进程都会有一个Application,所以Application的onCreate()可能会被调用多次),但进程的创建与初始化都需要时间,在这个动作完成之前,如果初始化的时间过长,屏幕上可能没有任何动静,用户会以为没有点到按钮。所以既不能停在原来的地方又没到显示新的界面,怎么办呢?这就有了StartingWindow(也称之为PreviewWindow)的出现,这样看起来就像Activity已经启动起来了,只是数据内容还没有初始化好。
StartingWindow一般出现在应用程序进程创建并初始化成功前,所以它是个临时窗口,对应的WindowType是TYPE_APPLICATION_STARTING。目的是告诉用户,系统已经接受到操作,正在响应,在程序初始化完成后实现目的UI,同时移除这个窗口。
这个StartingWindow就是我们要讨论的白屏和黑屏的“元凶”,一般情况下我们会对Application和Activity设置Theme,系统会根据设置的Theme初始化StartingWindow。Window布局的顶层是DecorView,StartingWindow显示一个空DecorView,但是会给这个DecorView应用这个Activity指定的Theme,如果这个Activity没有指定Theme就用Application的(Application系统要求必须设置Theme)。
当读到这里,你可能已经明白为什么会有黑/白屏2种颜色,因为通常我们会让我们的theme选择继承系统的dark或light主题。
App秒开实现
前面说过,任何一个Activity最终都会有一个Theme,无论是开发者自定义的还是有系统默认继承的得到的,而在样式中注意到有一个属性windowsBackground
,这个属性是设置Activity的启动窗口的背景(PS:当Activity被完全加载并绘制好,其启动窗口消失,之后就显示了Activity的布局)。
windowsBackground
支持直接设置图片填充窗口,也支持XML布局文件,不过类型是layer-list。
<style name="AppTheme.FullScreen" parent="@style/AppBaseTheme">
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@drawable/welcome</item>
</style>
「特别注意」:为保证启动速度,SplashActivity不要调用setContentView()
方法。因为Activity设置了layout,它在App完全初始化完成后才会显示,也会耗时。使用该启动画面实现也能兼容到上面说的白屏和黑屏的问题。通常情况下,建议把核心初始化代码考虑放到Application中,而引导页等最好单独再创建一个Activity,从Splash的onCreate(...)
中开启。
【参考博客】:
1.带你重新认识:Android Splash页秒开 Activity白屏 Activity黑屏
2.Android Splash界面解决白屏、黑屏等问题