Android冷启动白屏问题

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才能解决这种兼容性问题,希望对大家有所帮助。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容