Android冷启动白屏问题

简介: 1. 冷启动与热启动通常我们在使用某个应用程序时,都是点击桌面应用图标来启动该程序。你肯定或多或少的碰到过这种情况:应用启动的一刹那,手机会先白屏或者黑屏一段时间,然后再进入应用程序的主页,但是你退出应用后再次打开APP,确又发现白屏时间极短或者压根感觉不出来。

1. 冷启动与热启动

通常我们在使用某个应用程序时,都是点击桌面应用图标来启动该程序。你肯定或多或少的碰到过这种情况:应用启动的一刹那,手机会先白屏或者黑屏一段时间,然后再进入应用程序的主页,但是你退出应用后再次打开APP,确又发现白屏时间极短或者压根感觉不出来。

上面这种现象,涉及到2个概念:冷启动与热启动,我们先来理解下这2个术语是什么意思。

  1. 冷启动:当启动某个应用程序时,如果Android手机系统发现后台没有该应用程序的进程,则会先创建一个该应用程序进程,这种方式叫冷启动。
  2. 热启动:当启动某个应用程序时,系统后台已经有一个该应用程序的进程了,则不会再创建一个新的进程,这种方式叫热启动。通常,我们按返回键退出应用,按home键回到桌面,该应用进程还一直存活,再次启动应用都叫热启动。

需要注意的是,现在很多手机都有一键清理内存的功能,例如小米、华为等手机,还有类似腾讯手机管家之类的软件,也可实现类似功能。采用这些方式清理内存后,应用进程被杀掉了,再次启动应用,都属于冷启动了。

2. 白屏原因

通常情况下,白屏现象都是在冷启动情况下出现的,如果白屏时间过长,就会给人一种APP很卡顿的感觉。
应用程序启动时,系统会从zygote进程fork一个新的进程给程序使用,接着会创建和初始化Application类,再接着就是创建和初始化启动页Activity类了,只有启动页Activity能够在窗口显示出来之后,我们才能在设备上看到应用的程序的第一帧了。其大概流程可总结为:

从zygote进程fork出新进程 --> 创建Application类 --> Application.attachBaseContext() --> Application.onCreate() --> 创建入口Activity类 -> Activity.onCreate() --> Activity.onStart() --> Activity.onResume()

由此可见,冷启动可简单总结为3个步骤:
1.从zygote进程fork出一个新进程,这个步骤所需时间可忽略,因为我们无法控制;
2.创建Application类并初始化,主要是执行Application.onCreate()方法;
3.创建并初始化入口Activity类,并在窗口上绘制UI;

热启动时,相比冷启动少了1、2这2个步骤,步骤1我们不考虑,所以我们可初步判定Application.onCreate()执行比较耗时,才出现了白屏现象。可以自己写个demo验证,在Application.onCreate()方法里使线程停顿几秒钟,冷启动打开应用时就会发现白屏时间延长了几秒钟。

我们现在开发Android应用程序时,通常都会集成很多第三方SDK,这些SDK大多都需要在Application.onCreate()里进行初始化,同时我们自己的应用也有很多需要在这里进行初始化,这样导致了Application.onCreate()方法执行时间会很长。

但是Application.onCreate()执行时间过长跟应用启动白屏有什么关系呢?我们看到的界面,其实都是在手机window上绘制出来的,我们开发时的Activity并不是一个能看到的界面,它最终能显示出来,都需要通过measure、layout等过程之后,在window上绘制,我们才能看到界面。在应用启动之后,window就已经存在了,Application初始化时,会从配置的Theme里,读取一个名为“android:windowBackground”的属性,顾名思义就是窗口背景,该背景就会在window上绘制出来,同样我们也能看到了。如果我们采用的Theme里,没有覆盖该属性值,则会采用该Theme的默认值,大部分系统提供的Theme里,windowBackground都是白色,所以我们会看到白屏了。如果windowBackground属性值是黑色,我们就会看到黑屏了,如果是透明色,我们会发现应用卡顿之后才能看到程序界面。

3. 消除启动时的白屏/黑屏

3.1 优化Application.onCreate()方法

这里给出几点建议:

  • 尽量不要在Application里做耗时的操作,例如读写文件、数据库等;
  • 各种第三方SDK,看能否在需要使用的时候进行初始化;
  • 某些耗时的初始化方法能否放到线程里异步执行;

建议归建议,但实际开发时会发现很难,好多操作都非得放在Application里执行,移出去很困难,特别是很多老工程,你都不能预料到会出现什么幺蛾子。

3.2 设置android:windowBackground属性

在styles.xml里定义一个style,设置windowBackground属性:

    <style name=LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar.Fullscreen">
        <item name="android:windowBackground">@drawable/launch_bg</item>
        <item name="android:windowFullscreen">true</item>
    </style>

配置入口Activity的theme属性为上面定义的style:

<activity
    android:name=".LaunchActivity"
    android:configChanges="orientation|screenSize|keyboardHidden"
    android:screenOrientation="portrait"
    android:theme="@style/LaunchTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

windowBackground属性可以配置任意drawable,比方说与你启动页一样的图片,这样在冷启动时就能立马看到这张图片展示出来,然后跳转到启动页时,能做到视觉上的无缝过渡,这样就能让应用程序看起来是秒启动。

需要注意的是,这里的style我们继承自@android:style/Theme.Light.NoTitleBar.Fullscreen,如果你的LaunchActivity继承自AppCompatActivity,那么启动该Activity时会直接报错,因为AppCompatActivity必须采用继承自Theme.AppCompat的主题。

那有人说了,如果是这样,那我们就采用Theme.AppCompat.Light.NoActionBar好了,一般情况下这样也没问题。但是当你在某些有虚拟按键的手机上,会发现冷启动时你配置的图片占据了整个屏幕(底部虚拟按键的地方会挡住你的图片),然后进入启动页时,图片显示的区域又不包含底部虚拟按键的地方了,这样过渡就不平滑,用户体验不佳。但是采用我们之前定义的那个style,就不会出现这个问题了。这个问题困扰了我好久,后来才发现采用Theme.Light.NoTitleBar.Fullscreen才能解决这种兼容性问题,希望对大家有所帮助。

目录
相关文章
|
Web App开发 JavaScript 前端开发
安卓webview访问vue工程白屏/无响应/无法加载问题处理
本文目录 1. 问题出现 2. 尝试更换内嵌浏览器 3. 尝试各种babel配置 4. 二分排除法定位问题 5. 模拟器与真机测试还不一样 6. 总结 7. 反思
2518 0
|
XML 前端开发 定位技术
Android MVVM框架使用(十三)UI更新 (App启动白屏优化、适配Android10.0深色模式)
Android MVVM框架使用(十三)UI更新 (App启动白屏优化、适配Android10.0深色模式)
353 0
Android MVVM框架使用(十三)UI更新 (App启动白屏优化、适配Android10.0深色模式)
|
存储 Android开发 UED
Android 音乐APP(二)启动白屏优化、定位当前播放歌曲
Android 音乐APP(二)启动白屏优化、定位当前播放歌曲
236 0
Android 音乐APP(二)启动白屏优化、定位当前播放歌曲
|
数据库 Android开发 数据库管理
Android 天气APP(二十)增加欢迎页及白屏黑屏处理、展示世界国家/地区的城市数据
Android 天气APP(二十)增加欢迎页及白屏黑屏处理、展示世界国家/地区的城市数据
153 0
Android 天气APP(二十)增加欢迎页及白屏黑屏处理、展示世界国家/地区的城市数据
DHL
|
存储 算法 Java
Android 11 提高 App 冷启动速度 5% 以上
近一年多以来一直在做性能优化( OOM、Native、ANR 等等),在后面我也会写一些性能相关的文章,将自己学习和实践所得分享出来。以今天这篇文章作为开端。
DHL
256 0
Android 11 提高 App 冷启动速度 5% 以上
|
JavaScript Android开发
Cordova 打包 Vue 项目到Android打开白屏
Cordova 打包 Vue 项目到Android打开白屏问题解决方案,更改 publicPath 属性值为 ./。
|
Java Shell Android开发
【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )
【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )
290 0
【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )
|
开发工具 Android开发
Android冷启动优化解析
前言 事件发生在发包上线的前两天,在某某云进行移动测试时,提示冷启动速度低于平均值的问题,之前自己也曾尝试过优化,但是发现效果并不是很明显,作为一个有追求的开发者,趁着有点空闲时间,要好好研究一下冷启动优化问题。
1578 0
|
Android开发 数据格式 XML
Android之路 - 冷启动解决方案:实现秒开
前言 关于 splash 页面相信每个Android开发者都是非常熟悉的,而且很多人也遇到过需要在splash加个广告图片,然后延迟3秒在进入主页面,splash 应该只是一个启动页面,不应该放广告,但是那又能怎么样呢?又敌不过产品经理。
2744 0